What's the vulnerability?

The node-tar library (<= 7.5.2) fails to sanitize the linkpath of Link (hardlink) and SymbolicLink entries when preservePaths is false (the default secure behavior). This allows malicious archives to bypass the extraction root restriction, leading to Arbitrary File Overwrite via hardlinks and Symlink Poisoning via absolute symlink targets.

Root Cause Analysis

## Summary
`node-tar` ≤ 7.5.2 does not sanitize the `linkpath` field of `Link` entries when extracting with `preservePaths=false`. A malicious TAR can hardlink a file inside the extraction root (e.g., `payload`) to an absolute path outside the root (e.g., `/tmp/secret.txt`). When the extractor later writes to the in-root path, it actually overwrites the arbitrary external file, enabling path-escape and arbitrary file overwrite.

## Impact
- **Affected component:** `node-tar` hardlink extraction logic (`unpack.ts`)
- **Affected versions:** 7.5.2 and earlier (fixed in 7.5.3)
- **Risk:** High. Attackers controlling TAR input can overwrite any writable file reachable by the extracting process, enabling configuration tampering or code execution in build/CI pipelines.

## Root Cause
`node-tar` resolves hardlink targets with `path.resolve(this.cwd, entry.linkpath)` but never checks that the resulting path still resides under `cwd`. Because `path.resolve` returns the second operand unchanged when it is absolute, an attacker can supply an absolute `linkpath`. The library then creates a hardlink from the in-root `entry.path` to the attacker-chosen absolute file. Subsequent writes to `entry.path` therefore modify the external target. Fix commit (upstream): https://github.com/isaacs/node-tar/commit/340eb285b6d986e91969a1170d7fe9b0face405e adds validation to reject absolute link targets.

## Reproduction Steps
1. Run `repro/reproduction_steps.sh`.
2. Script installs Node dependencies (including `node-tar@7.5.2`), crafts a malicious TAR with a hardlink pointing to `secret.txt` outside the extraction root, extracts it with `tar.x({preservePaths:false})`, writes `EXPLOIT` into `out/payload`, and finally reads `secret.txt`.
3. Reproduction succeeds when the script reports `secret.txt now contains: EXPLOIT` and exits 0.

## Evidence
- Logs: `logs/repro_20260117075559.log`, `logs/repro_20260117075603.log`
- Key excerpt: `secret.txt now contains: EXPLOIT` followed by `Reproduction successful: secret.txt overwritten via hardlink escape`
- Environment: Node v22.21.1, npm 10.9.4 as captured in the log prologue.

## Recommendations / Next Steps
- Upgrade to `node-tar` ≥ 7.5.3 where absolute link targets are rejected.
- When possible, reject TAR archives containing `Link`/`SymbolicLink` entries or perform manual validation that resolved paths stay inside the extraction root.
- Add regression tests that extract crafted archives with absolute `linkpath`s to ensure future sanitization.

## Additional Notes
- Script is idempotent: executed twice consecutively; both runs succeeded and produced separate timestamped logs.
- Limitation: PoC demonstrates hardlink overwrite only; symlink poisoning is related but not exercised here.
One Command

Verify with pruva-verify

Run the Pruva CLI to automatically fetch and execute the reproduction script.

pruva-verify REPRO-2026-00064
or pruva-verify GHSA-8qq5-rm4j-mr97
Install: curl -fsSL https://pruva.dev/install.sh | sh

Or Run Manually

1

Download the script

curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00064/artifacts/reproduction_steps.sh
2

Make executable

chmod +x reproduction_steps.sh
3

Run the script

./reproduction_steps.sh
Run in a VM, container, or disposable environment. This exploits a real vulnerability.

How Pruva Reproduced This

Watch the AI agent's step-by-step process.

Loading session...

Artifacts

No artifacts available