UNIX Symbolic Link (Symlink) Following in @npmcli/arborist
Description
@npmcli/arborist, the library that calculates dependency trees and manages the node_modules folder hierarchy for the npm command line interface, aims to guarantee that package dependency contracts will be met, and the extraction of package contents will always be performed into the expected folder. This is, in part, accomplished by resolving dependency specifiers defined in package.json manifests for dependencies with a specific name, and nesting folders to resolve conflicting dependencies. When multiple dependencies differ only in the case of their name, Arborist's internal data structure saw them as separate items that could coexist within the same level in the node_modules hierarchy. However, on case-insensitive file systems (such as macOS and Windows), this is not the case. Combined with a symlink dependency such as file:/some/path, this allowed an attacker to create a situation in which arbitrary contents could be written to any location on the filesystem. For example, a package pwn-a could define a dependency in their package.json file such as "foo": "file:/some/path". Another package, pwn-b could define a dependency such as FOO: "file:foo.tgz". On case-insensitive file systems, if pwn-a was installed, and then pwn-b was installed afterwards, the contents of foo.tgz would be written to /some/path, and any existing contents of /some/path would be removed. Anyone using npm v7.20.6 or earlier on a case-insensitive filesystem is potentially affected. This is patched in @npmcli/arborist 2.8.2 which is included in npm v7.20.7 and above.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Arborist's case-insensitive file system handling allows symlink-based arbitrary file write via case-conflicting dependencies, patched in npm v7.20.7.
Vulnerability
@npmcli/arborist versions prior to 2.8.2 (included in npm v7.20.6 and earlier) mishandle dependency names that differ only in case on case-insensitive file systems (macOS, Windows). The internal data structure treats foo and FOO as separate entries, but the filesystem treats them as the same. When combined with a symlink dependency (e.g., "foo": "file:/some/path"), this allows an attacker to redirect extraction to an arbitrary location [2][3].
Exploitation
An attacker must publish or install two packages with case-conflicting dependency names. For example, package pwn-a declares "foo": "file:/some/path" and package pwn-b declares "FOO": "file:foo.tgz". On a case-insensitive filesystem, installing pwn-a then pwn-b causes the contents of foo.tgz to be written to /some/path, overwriting any existing content [2][3]. No special privileges beyond the ability to install packages are required.
Impact
Successful exploitation results in arbitrary file creation or overwrite at any location on the filesystem, with the privileges of the user running npm install. This can lead to arbitrary code execution (e.g., overwriting executable scripts or configuration files) and full system compromise [3].
Mitigation
The vulnerability is fixed in @npmcli/arborist version 2.8.2, which is included in npm v7.20.7 and later. Users on case-insensitive file systems should upgrade immediately. No workaround is available [2][3].
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
@npmcli/arboristnpm | < 2.8.2 | 2.8.2 |
Affected products
12- ghsa-coords11 versionspkg:npm/%40npmcli/arboristpkg:rpm/opensuse/nodejs12&distro=openSUSE%20Leap%2015.2pkg:rpm/opensuse/nodejs12&distro=openSUSE%20Leap%2015.3pkg:rpm/opensuse/nodejs14&distro=openSUSE%20Leap%2015.2pkg:rpm/opensuse/nodejs14&distro=openSUSE%20Leap%2015.3pkg:rpm/suse/nodejs12&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Web%20and%20Scripting%2012pkg:rpm/suse/nodejs12&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Web%20and%20Scripting%2015%20SP2pkg:rpm/suse/nodejs12&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Web%20and%20Scripting%2015%20SP3pkg:rpm/suse/nodejs14&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Web%20and%20Scripting%2012pkg:rpm/suse/nodejs14&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Web%20and%20Scripting%2015%20SP2pkg:rpm/suse/nodejs14&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Web%20and%20Scripting%2015%20SP3
< 2.8.2+ 10 more
- (no CPE)range: < 2.8.2
- (no CPE)range: < 12.22.7-lp152.3.21.1
- (no CPE)range: < 12.22.7-4.22.1
- (no CPE)range: < 14.18.1-lp152.17.1
- (no CPE)range: < 14.18.1-15.21.2
- (no CPE)range: < 12.22.9-1.38.1
- (no CPE)range: < 12.22.7-4.22.1
- (no CPE)range: < 12.22.7-4.22.1
- (no CPE)range: < 14.18.1-6.18.2
- (no CPE)range: < 14.18.1-15.21.2
- (no CPE)range: < 14.18.1-15.21.2
- npm/arboristv5Range: < 2.8.2
Patches
0No patches discovered yet.
Vulnerability mechanics
AI mechanics synthesis has not run for this CVE yet.
References
7- github.com/advisories/GHSA-2h3h-q99f-3fhcghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2021-39134ghsaADVISORY
- cert-portal.siemens.com/productcert/pdf/ssa-389290.pdfghsax_refsource_CONFIRMWEB
- github.com/npm/arborist/security/advisories/GHSA-2h3h-q99f-3fhcghsax_refsource_CONFIRMWEB
- www.npmjs.com/package/%40npmcli/arboristmitrex_refsource_MISC
- www.npmjs.com/package/@npmcli/arboristghsaWEB
- www.oracle.com/security-alerts/cpuoct2021.htmlghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.