CVE-2021-39134

Improper Link Resolution Before File Access ('Link Following')
Affects
Node.js
in
Node.js
No items found.
Versions
>=12.0.0 <12.22.6 >=14.0.0 <14.17.6 >=15.0.0 <=15.14.0 >=16.0.0 <16.8.0

Patch Available.

Exclamation circle icon
Patch Available

This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.

Overview

Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine. It uses an event-driven, non-blocking I/O model and is widely used for web applications and server-side development. Every official Node.js distribution ships with npm, the default package manager, so the npm version a developer runs is usually the one bundled with their Node.js release. Starting with npm 7, npm builds and installs the dependency tree through @npmcli/arborist, the library that calculates dependency trees and manages the node_modules folder hierarchy.

A vulnerability (CVE-2021-39134) has been identified in @npmcli/arborist, as bundled with npm in Node.js. Arborist is meant to extract every package into its expected folder, and it resolves name conflicts by nesting folders. However, it treated dependency names that differ only in letter case as separate entries at the same level of node_modules, while case-insensitive file systems treat them as the same folder. Combined with a symlink dependency, this lets a malicious package cause arbitrary contents to be written to, and existing contents removed from, any location on the file system the installing user can write to.

This flaw maps to CWE-61 (UNIX Symbolic Link (Symlink) Following), where software operating on a file or folder does not account for a symbolic link that points outside the area it is meant to control. In arborist, a dependency name that collides by case with a file: symlink dependency sends extraction through the link to a folder of the attacker's choosing. Because npm runs with the developer's or build system's permissions, overwriting files there can lead to arbitrary file creation, file overwrite and code execution.

An attacker exploits this by publishing or supplying two packages: one that declares a dependency such as "foo": "file:/some/path", and another that declares a case variant such as "FOO": "file:foo.tgz". If both are installed, in that order, on a case-insensitive file system such as the defaults on macOS and Windows, the contents of foo.tgz are written to /some/path and whatever was there is removed. The vulnerable arborist was bundled with npm 7 up to 7.20.6, which shipped with Node.js 15.x and Node.js 16.x before 16.8.0. Node.js also addressed this CVE in its 12.22.6 and 14.17.6 security releases, which listed the 12.x and 14.x release lines as vulnerable.

‍

Details

Module Info

  • Product: Node.js
  • Affected packages: @npmcli/arborist (bundled with npm in Node.js)
  • Affected versions: >=12.0.0 <12.22.6 >=14.0.0 <14.17.6 >=15.0.0 <=15.14.0 >=16.0.0 <16.8.0
  • GitHub repository: https://github.com/nodejs/node
  • Published packages: https://nodejs.org/en/download
  • Package manager: Not applicable; Node.js is distributed as runtime builds from nodejs.org rather than as a published npm package
  • Fixed in: Node.js 16.8.0 (August 25, 2021), which bundled npm 7.21.0 with @npmcli/arborist 2.8.2, and Node.js 12.22.6 and 14.17.6 (August 31, 2021), whose security releases listed this CVE as addressed; Node.js NES v14.21.4 (14.x line, shipped August 24, 2024) and v12.22.13 (12.x line, shipped November 10, 2025), which also list this CVE as fixed. Node.js 15.x never received a fix

Vulnerability Info

This High-severity vulnerability is found in @npmcli/arborist 2.8.1 and earlier, the dependency-tree library bundled with npm and therefore with Node.js. NVD assigns a CVSS v3.1 score of 7.8.

Arborist is supposed to guarantee that each package is extracted into its own expected folder. In the vulnerable versions, its internal map of a folder's children was case-sensitive, so "foo" and "FOO" could coexist in the tree even though a case-insensitive file system resolves them to one folder, and extraction would follow an existing symlink at that path. Arborist 2.8.2 fixes both halves: just before extraction, any target that is not a real directory is moved aside, and the children map is replaced with a case-insensitive one so the collision is detected. See the arborist advisory for the details of the change.

Exploitation requires the victim to install attacker-controlled packages, for example as transitive dependencies, on a case-insensitive file system. No privileges on the target system are needed beyond getting the packages installed, and the impact covers the confidentiality, integrity and availability of anything the installing account can write.

Note: Installs on case-sensitive file systems, the default on most Linux systems, are not exposed by this issue.

‍

Mitigation

The Node.js 12.x, 14.x, 15.x and 16.x release lines are all past their support window and will not receive further upstream updates. For more information see here.

Users of the affected components should apply one of the following mitigations:

  • Upgrade to a currently supported Node.js LTS release (22.x or 24.x), both of which bundle an npm version that includes this fix.
  • Migrate affected applications away from the End-of-Life Node.js release lines.
  • Leverage a commercial support partner like HeroDevs for post-EOL security support, through Node.js NES.

‍

Credits

  • ginkoid (analyst)
  • chen-robert (analyst)
Vulnerability Details
Severity
Level
CVSS Assessment
Low
>=0 <4
Medium
>=4 <6
High
>=6 <8
Critical
>=8 <10
High
ID
CVE-2021-39134
PROJECT Affected
Node.js
Versions Affected
>=12.0.0 <12.22.6 >=14.0.0 <14.17.6 >=15.0.0 <=15.14.0 >=16.0.0 <16.8.0
NES Versions Affected
Published date
October 1, 2026
≈ Fix date
August 24, 2024
Category
Improper Link Resolution Before File Access ('Link Following')
Vex Document
Download VEXHow do I use it?
Sign up for the latest vulnerability alerts fixed in
NES for Node.js
Rss feed icon
Subscribe via RSS
or

By submitting the form I acknowledge receipt of our Privacy Policy.

Thanks for signing up for our Newsletter! We look forward to connecting with you.
Oops! Something went wrong while submitting the form.