CVE-2021-39134 in arborist
Summary
by MITRE • 08/31/2021
`@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.
VulDB is the best source for vulnerability data and more expert information about this specific topic.
Analysis
by VulDB Data Team • 09/03/2021
The vulnerability described in CVE-2021-39134 resides within the @npmcli/arborist library, which serves as the core dependency resolution engine for the npm package manager. This library is responsible for calculating dependency trees and managing the node_modules folder hierarchy, ensuring that package dependency contracts are maintained during installation processes. The flaw manifests in how Arborist handles case-insensitive file system interactions, specifically when processing dependencies that differ only by case. The library's internal data structures treat these case-differentiated dependencies as distinct entities that can coexist at the same hierarchical level within the node_modules structure, which creates a fundamental mismatch with the actual behavior of case-insensitive file systems like those found on macOS and Windows operating systems.
The technical exploitation of this vulnerability occurs through a carefully crafted dependency chain involving symlinked dependencies with case variations. When an attacker constructs package manifests with dependencies that are identical except for case differences, and combines them with file:// protocol symlinks, the system can be manipulated to overwrite arbitrary files on the target filesystem. Specifically, if package pwn-a defines a dependency as "foo": "file:/some/path" and package pwn-b defines a dependency as "FOO": "file:foo.tgz", the installation sequence can result in the contents of foo.tgz being written to /some/path while potentially destroying existing content at that location. This behavior represents a critical path traversal vulnerability that allows attackers to write files to arbitrary locations on the filesystem, bypassing normal security boundaries that should protect system integrity.
The operational impact of this vulnerability is particularly severe for users operating on case-insensitive file systems, which includes the majority of desktop operating systems including macOS and Windows. The vulnerability affects npm versions 7.20.6 and earlier, making a substantial portion of the npm user base susceptible to exploitation. Attackers could leverage this weakness to overwrite critical system files, inject malicious code into existing packages, or manipulate the package installation process to achieve privilege escalation or persistent access. The vulnerability's exploitation requires minimal privileges and can be executed through normal package installation workflows, making it particularly dangerous in automated deployment scenarios or when users install packages from untrusted sources. This issue directly relates to CWE-22 Path Traversal and CWE-73 Path Traversal, as it allows attackers to manipulate file system paths beyond intended boundaries.
The mitigation for this vulnerability is provided through the patched version of @npmcli/arborist 2.8.2, which is included in npm v7.20.7 and subsequent releases. The fix addresses the core issue by modifying how the library handles case-insensitive file system interactions, ensuring that dependencies with case variations are properly resolved and that symlinked dependencies are processed with appropriate safeguards against path manipulation. System administrators and developers should immediately update their npm installations to versions 7.20.7 or later to protect against this vulnerability. Additionally, organizations should review their package management workflows and implement proper dependency validation procedures to minimize the risk of installing packages containing maliciously crafted dependencies that could exploit this or similar vulnerabilities. The fix aligns with ATT&CK technique T1059 Command and Scripting Interpreter and T1068 Exploitation for Privilege Escalation, as it addresses a path manipulation weakness that could be leveraged for privilege escalation through package installation processes.