GHSA-83g3-92jg-28cx
HIGHArbitrary File Read/Write via Hardlink Target Escape Through Symlink Chain in node-tar Extraction
EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
Blast Radius
Weekly download volume for affected packages — a proxy for how broadly this vulnerability is deployed.
tarnpmDescription
Summary
tar.extract() in Node tar allows an attacker-controlled archive to create a hardlink inside the extraction directory that points to a file outside the extraction root, using default options.
This enables arbitrary file read and write as the extracting user (no root, no chmod, no preservePaths).
Severity is high because the primitive bypasses path protections and turns archive extraction into a direct filesystem access primitive.
Details
The bypass chain uses two symlinks plus one hardlink:
a/b/c/up -> ../..a/b/escape -> c/up/../..exfil(hardlink) ->a/b/escape/<target-relative-to-parent-of-extract>
Why this works:
-
Linkpath checks are string-based and do not resolve symlinks on disk for hardlink target safety.
- See
STRIPABSOLUTEPATHlogic in:../tar-audit-setuid - CVE/node_modules/tar/dist/commonjs/unpack.js:255../tar-audit-setuid - CVE/node_modules/tar/dist/commonjs/unpack.js:268../tar-audit-setuid - CVE/node_modules/tar/dist/commonjs/unpack.js:281
- See
-
Hardlink extraction resolves target as
path.resolve(cwd, entry.linkpath)and then callsfs.link(target, destination).../tar-audit-setuid - CVE/node_modules/tar/dist/commonjs/unpack.js:566../tar-audit-setuid - CVE/node_modules/tar/dist/commonjs/unpack.js:567../tar-audit-setuid - CVE/node_modules/tar/dist/commonjs/unpack.js:703
-
Parent directory safety checks (
mkdir+ symlink detection) are applied to the destination path of the extracted entry, not to the resolved hardlink target path.../tar-audit-setuid - CVE/node_modules/tar/dist/commonjs/unpack.js:617../tar-audit-setuid - CVE/node_modules/tar/dist/commonjs/unpack.js:619../tar-audit-setuid - CVE/node_modules/tar/dist/commonjs/mkdir.js:27../tar-audit-setuid - CVE/node_modules/tar/dist/commonjs/mkdir.js:101
As a result, exfil is created inside extraction root but linked to an external file. The PoC confirms shared inode and successful read+write via exfil.
PoC
hardlink.js Environment used for validation:
- Node:
v25.4.0 - tar:
7.5.7 - OS: macOS Darwin 25.2.0
- Extract options: defaults (
tar.extract({ file, cwd }))
Steps:
-
Prepare/locate a
tarmodule. Ifrequire('tar')is not available locally, setTAR_MODULEto an absolute path to a tar package directory. -
Run:
TAR_MODULE="$(cd '../tar-audit-setuid - CVE/node_modules/tar' && pwd)" node hardlink.js
- Expected vulnerable output (key lines):
same_inode=true
read_ok=true
write_ok=true
result=VULNERABLE
Interpretation:
same_inode=true: extractedexfiland external secret are the same file object.read_ok=true: readingexfilleaks external content.write_ok=true: writingexfilmodifies external file.
Impact
Vulnerability type:
- Arbitrary file read/write via archive extraction path confusion and link resolution.
Who is impacted:
- Any application/service that extracts attacker-controlled tar archives with Node
tardefaults. - Impact scope is the privileges of the extracting process user.
Potential outcomes:
- Read sensitive files reachable by the process user.
- Overwrite writable files outside extraction root.
- Escalate impact depending on deployment context (keys, configs, scripts, app data).
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 📦npm | tar | all versions | 7.5.8 |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for tar. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.
Fix
Update tar to 7.5.8 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-83g3-92jg-28cx is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 pinpoints whether GHSA-83g3-92jg-28cx is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.
Tailored to GHSA-83g3-92jg-28cx. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Frequently Asked Questions
Is GHSA-83g3-92jg-28cx in your dependencies?
O3 detects GHSA-83g3-92jg-28cx across npm dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.