CVE-2026-40931
JavaScript vulnerability analysis and mitigation

Overview

CVE-2026-40931 is a symlink path traversal vulnerability in the compressing npm package (node-modules/compressing) that allows a local attacker to bypass the security patch introduced for CVE-2026-24884 and write files outside the intended extraction directory. It affects all versions prior to 1.10.5 and versions 2.0.0 through 2.1.0. The vulnerability was published on April 21, 2026, with patches released in versions 1.10.5 and 2.1.1. It carries a CVSS v3.1 base score of 7.8 (High) per Feedly/NVD, though the GitHub Security Advisory rates it 8.4 (High) (GitHub Advisory, Red Hat CVE).

Technical details

The root cause is classified as CWE-59 (Improper Link Resolution Before File Access / 'Link Following'). The vulnerable function isPathWithinParent() in lib/utils.js performs only a string-based check — using path.resolve() to verify that a resolved path starts with the destination directory string — without inspecting the actual filesystem state. This creates a "Logical vs. Physical" divergence: if an attacker pre-plants a symbolic link (e.g., config/etc) within the extraction directory, path.resolve() returns a path that passes the string check, but the OS kernel follows the symlink to a sensitive location outside the intended root when fs.writeFile() is called. The primary attack vector is supply chain delivery via git clone, since Git natively preserves and restores symlinks, automatically deploying the malicious symlink to a victim's machine without any additional attacker access beyond hosting a repository. A detailed PoC with step-by-step commands is publicly available (GitHub Advisory).

Impact

Successful exploitation enables arbitrary file write outside the intended extraction directory, which can lead to privilege escalation (e.g., overwriting /etc/passwd or /etc/shadow), remote code execution by overwriting executable binaries or shell startup scripts (.bashrc, .profile), and data corruption or permanent loss of application data. In environments where the extraction process runs as a high-privilege user, the impact is especially severe, potentially granting full system compromise. The supply chain delivery mechanism means any downstream project using the vulnerable library and extracting archives from untrusted or attacker-controlled repositories is at risk (GitHub Advisory).

Exploitability

A public proof-of-concept exploit with detailed step-by-step reproduction instructions (bash/JavaScript) is available in the GitHub Security Advisory. The PoC demonstrates arbitrary file overwrite via symlink poisoning delivered through a standard git clone workflow, requiring no social engineering beyond the victim cloning a repository. There is no evidence of in-the-wild exploitation at this time, and the vulnerability is not listed in the CISA KEV catalog. The EPSS score is 0.014% (very low probability of exploitation in the near term). Qualys has detection coverage under detection ID 5011222 (GitHub Advisory, Feedly).

Exploitation steps

  1. Attacker Preparation — Create Poisoned Repository: The attacker creates a Git repository containing a symbolic link named to match an expected extraction path component (e.g., ln -s /tmp/fake_root/etc/passwd config_file). This symlink points to a sensitive target file outside the intended extraction directory.
  2. Generate Malicious Archive Payload: The attacker creates a .tar archive containing a plain file entry with the same name as the symlink (e.g., config_file) and malicious content (e.g., root:PWNED_BY_SUPPLY_CHAIN_ATTACK), using a script with tar-stream.
  3. Push to Repository: Both the symlink and the malicious .tar payload are committed and pushed to the attacker-controlled GitHub repository. Git preserves the symlink as a first-class object.
  4. Victim Clones Repository: The victim performs a standard git clone of the attacker's repository. Git automatically restores the symlink on the victim's filesystem, pre-planting the poisoned path without any additional attacker access.
  5. Victim Extracts Archive: The victim runs an application that uses the compressing library to extract the bundled .tar payload into the cloned directory (e.g., await compressing.tar.uncompress('./payload.tar', './')).
  6. Bypass Triggered — Arbitrary File Write: isPathWithinParent() validates the path string ./config_file as safe (it starts with the destination directory). When fs.writeFile() is called, the OS kernel follows the pre-existing symlink to the sensitive target (e.g., /tmp/fake_root/etc/passwd), overwriting it with the attacker's payload content.
  7. Post-Exploitation: Depending on the target file overwritten and the privilege level of the process, the attacker can achieve privilege escalation, code execution on next login/boot, or data destruction (GitHub Advisory).

Indicators of compromise

  • File System: Unexpected symbolic links in directories used as extraction targets by the compressing library; symlinks pointing to sensitive system files (e.g., /etc/passwd, /etc/shadow, shell startup scripts); unexpected modification timestamps on system configuration files or executables.
  • Logs: Node.js application logs showing successful extraction of archives into directories containing pre-existing symlinks; file access logs (e.g., auditd) recording writes to sensitive paths (/etc/passwd, /etc/shadow) by a Node.js process.
  • Process: Node.js (node) processes performing file write operations to paths outside the expected application directory; unexpected child processes spawned after archive extraction (indicating overwritten startup scripts or binaries were executed).
  • Network: Outbound connections from developer workstations to unfamiliar Git repository hosts immediately before exploitation; cloning of repositories not in the organization's approved list (GitHub Advisory).

Mitigation and workarounds

Upgrade the compressing npm package to version 1.10.5 (for the 1.x branch) or 2.1.1 (for the 2.x branch), which implement filesystem-aware path validation using fs.lstatSync() to recursively check each path segment for symbolic links before any write operation. For environments unable to patch immediately: apply the principle of least privilege to restrict which users and processes can invoke the compressing library; restrict symbolic link creation in directories used for archive extraction; and avoid extracting untrusted archives into directories that may contain pre-existing symbolic links. Additionally, audit Git repositories cloned from external or untrusted sources for embedded symlinks before running any extraction workflows (GitHub Advisory, Feedly).

Community reactions

A technical write-up titled "Uncovering the Blind Spot: Bypassing a Security Patch (CVE-2026-24884) to Achieve Arbitrary File Write" was published on InfoSec Writeups, detailing the patch bypass research (InfoSec Writeups). Undercode News covered the vulnerability under the headline "Silent Supply Chain Break: CVE-2026-40931 Uncovers a Dangerous Patch Bypass in Node.js Compressing Library," highlighting the supply chain risk angle (Undercode News). CyberPress also reported on the CVE-2026-24884 patch bypass, noting the incomplete fix (CyberPress). The vulnerability was noted on Mastodon by @thehackerwire, contributing to broader community awareness.

Additional resources


SourceThis report was generated using AI

Related JavaScript vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-77415CRITICAL9.3
  • JavaScript logoJavaScript
  • jsonata
NoYesAug 21, 2026
CVE-2026-77414CRITICAL9.3
  • JavaScript logoJavaScript
  • jsonata
NoYesAug 21, 2026
CVE-2026-77413CRITICAL9.3
  • JavaScript logoJavaScript
  • jsonata
NoYesAug 21, 2026
CVE-2026-63421HIGH7.5
  • JavaScript logoJavaScript
  • @keystone-6/core
NoYesAug 21, 2026
CVE-2026-53509MEDIUM5.7
  • JavaScript logoJavaScript
  • @aborruso/ckan-mcp-server
NoYesAug 21, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management