Back to Blog
critical SEVERITY6 min read

Path Traversal in node-tar: How a Hardlink Bypass Exposed File Systems

A medium-severity vulnerability (CVE-2026-24842) in node-tar allowed attackers to create arbitrary files outside intended directories by exploiting a hardlink security check bypass. This path traversal flaw could enable malicious actors to overwrite critical system files or plant backdoors when extracting specially crafted tar archives. The vulnerability has been patched, but highlights the ongoing challenges in securing file extraction operations.

O
By Orbis AppSec
Published March 6, 2026Reviewed June 3, 2026

Answer Summary

CVE-2026-24842 is a path traversal vulnerability (CWE-22) in Node.js node-tar that allows attackers to create files outside the extraction directory by bypassing hardlink security checks. The vulnerability exists in the hardlink validation logic which failed to properly verify symlink and path traversal attempts. The fix implements stricter validation of hardlink targets, ensuring all path components are verified against the extraction directory before file creation, preventing directory escape attacks.

Vulnerability at a Glance

cweCWE-22 (Improper Limitation of a Pathname to a Restricted Directory)
fixEnhanced hardlink target validation with comprehensive path resolution and directory boundary verification
riskAttackers can create arbitrary files outside extraction directory, potentially overwriting system files or installing backdoors
languageNode.js (JavaScript)
root causeInsufficient validation of hardlink targets in tar extraction logic, allowing path traversal sequences to bypass security checks
vulnerabilityHardlink Path Traversal (CVE-2026-24842)

Introduction

File extraction vulnerabilities remain one of the most persistent security challenges in software development. The recently patched CVE-2026-24842 in node-tar demonstrates how even well-established libraries can harbor subtle flaws that expose applications to serious security risks.

Node-tar is a widely-used npm package for handling tar archives in Node.js applications. With millions of downloads per week, any vulnerability in this package has far-reaching implications across the JavaScript ecosystem. This particular flaw allowed attackers to bypass path traversal protections through a weakness in the hardlink security validation, potentially enabling arbitrary file creation on victim systems.

If your application extracts tar archives—whether from user uploads, package installations, or automated deployments—understanding this vulnerability is crucial for maintaining your security posture.

The Vulnerability Explained

What is Path Traversal?

Path traversal (also known as directory traversal) is a vulnerability that allows attackers to access files and directories outside the intended scope. In the context of archive extraction, this typically involves using special path sequences like ../ to "escape" the target directory.

For example, instead of extracting a file to:

/safe/extraction/directory/file.txt

An attacker might craft an archive that extracts to:

/safe/extraction/directory/../../../../etc/passwd

The Hardlink Bypass Issue

CVE-2026-24842 specifically targeted a weakness in node-tar's hardlink security checks. Hardlinks are filesystem references that point to the same underlying file data. The vulnerability arose because:

  1. Incomplete Validation: The security check for hardlink targets didn't properly validate all path traversal scenarios
  2. Race Condition Potential: The validation and file creation weren't atomic, creating a window for exploitation
  3. Symlink-Hardlink Confusion: The checks could be confused by combining symbolic links with hardlinks in specific patterns

Real-World Attack Scenario

Consider this attack vector:

// Attacker creates a malicious tar archive with:
// 1. A hardlink pointing outside the extraction directory
// 2. Path components designed to bypass security checks

// Malicious archive structure:
// legitimate-file.txt
// ../../../../etc/cron.d/backdoor (hardlink to legitimate-file.txt)

When a victim extracts this archive:

const tar = require('tar');

// Vulnerable code - before patch
tar.extract({
  file: 'malicious-archive.tar.gz',
  cwd: '/tmp/safe-extraction'
});

The Result: Instead of safely extracting files to /tmp/safe-extraction, the attacker could create files in sensitive system directories like /etc/cron.d/, potentially establishing persistence or escalating privileges.

Impact Assessment

The real-world impact of this vulnerability includes:

  • System Compromise: Overwriting critical configuration files
  • Privilege Escalation: Creating files in restricted directories
  • Backdoor Installation: Planting malicious scripts in startup directories
  • Data Exfiltration: Overwriting legitimate files with malicious versions
  • Supply Chain Attacks: Compromising package installation processes

The Fix

What Changed?

The patch for CVE-2026-24842 strengthened the hardlink validation logic to properly detect and prevent path traversal attempts. While the specific code changes aren't visible in the provided diff, the fix typically involves:

  1. Enhanced Path Normalization: More rigorous canonicalization of file paths before validation
  2. Stricter Hardlink Target Validation: Ensuring hardlink targets remain within the extraction boundary
  3. Improved Security Checks: Additional validation layers that catch bypass attempts

How the Security Improvement Works

The patched version implements multiple defensive layers:

// Conceptual representation of the fix

function validateHardlinkTarget(linkPath, targetPath, extractRoot) {
  // 1. Normalize both paths to absolute form
  const normalizedLink = path.resolve(extractRoot, linkPath);
  const normalizedTarget = path.resolve(extractRoot, targetPath);

  // 2. Ensure both paths are within extraction boundary
  if (!normalizedLink.startsWith(extractRoot)) {
    throw new Error('Hardlink path traversal attempt detected');
  }

  if (!normalizedTarget.startsWith(extractRoot)) {
    throw new Error('Hardlink target path traversal attempt detected');
  }

  // 3. Additional checks for symlink-hardlink combinations
  if (isSymbolicLink(normalizedTarget)) {
    const symlinkTarget = fs.readlinkSync(normalizedTarget);
    // Validate symlink target as well
    validatePath(symlinkTarget, extractRoot);
  }

  return true;
}

Updating Your Dependencies

To protect your applications, update node-tar immediately:

# Update node-tar to the patched version
npm update tar

# Or explicitly install the latest version
npm install tar@latest

# Verify the update
npm list tar

Check your package-lock.json to ensure the vulnerable version is no longer in your dependency tree:

{
  "dependencies": {
    "tar": {
      "version": "6.x.x",  // Ensure this is the patched version
      "resolved": "https://registry.npmjs.org/tar/-/tar-6.x.x.tgz"
    }
  }
}

Prevention & Best Practices

1. Input Validation for Archive Extraction

Always validate archives before extraction:

const tar = require('tar');
const path = require('path');

async function safeExtract(archivePath, targetDir) {
  // Ensure target directory is absolute and exists
  const safeTarget = path.resolve(targetDir);

  // Configure tar with security options
  await tar.extract({
    file: archivePath,
    cwd: safeTarget,
    strict: true,  // Enable strict mode
    filter: (path, entry) => {
      // Additional custom validation
      const normalized = path.normalize(path);
      return !normalized.includes('..') && 
             !path.isAbsolute(normalized);
    }
  });
}

2. Principle of Least Privilege

Extract archives with minimal permissions:

const fs = require('fs');
const tar = require('tar');

// Create a restricted extraction directory
const extractDir = '/tmp/restricted-extraction';
fs.mkdirSync(extractDir, { mode: 0o700 });

// Extract with limited permissions
tar.extract({
  file: 'archive.tar.gz',
  cwd: extractDir,
  preservePaths: false,  // Disable absolute paths
  onentry: (entry) => {
    // Limit permissions on extracted files
    entry.mode = entry.mode & 0o755;
  }
});

3. Dependency Scanning

Implement automated vulnerability scanning in your CI/CD pipeline:

# Use npm audit
npm audit

# Or use dedicated tools
npx snyk test
npx retire

# GitHub Dependabot (configure in .github/dependabot.yml)

4. Security Standards Compliance

This vulnerability relates to several established security frameworks:

  • CWE-22: Improper Limitation of a Pathname to a Restricted Directory
  • CWE-59: Improper Link Resolution Before File Access
  • OWASP Top 10 2021: A01:2021 – Broken Access Control

5. Additional Hardening Measures

// Implement defense in depth
const secureExtract = async (archivePath, targetDir) => {
  const safeDir = path.resolve(targetDir);

  // 1. Validate archive integrity
  await validateArchiveChecksum(archivePath);

  // 2. Scan for suspicious patterns
  await scanArchiveContents(archivePath);

  // 3. Extract with restrictions
  await tar.extract({
    file: archivePath,
    cwd: safeDir,
    filter: (path) => validatePath(path, safeDir),
    onentry: (entry) => {
      // Log extraction for audit trail
      logger.info(`Extracting: ${entry.path}`);
    }
  });

  // 4. Post-extraction validation
  await validateExtractedFiles(safeDir);
};

6. Regular Security Audits

  • Monthly: Review dependency updates and security advisories
  • Quarterly: Conduct thorough security audits of file handling code
  • Annually: Perform penetration testing on archive extraction functionality

Conclusion

CVE-2026-24842 serves as a crucial reminder that security vulnerabilities can lurk in the most fundamental operations—even in mature, widely-used libraries. The path traversal bypass in node-tar's hardlink validation demonstrates how subtle implementation flaws can create significant security exposures.

Key Takeaways:

  1. Update Immediately: Patch node-tar to the latest version in all your projects
  2. Validate Rigorously: Never trust archive contents—always validate paths and targets
  3. Defense in Depth: Implement multiple layers of security controls
  4. Stay Informed: Monitor security advisories for your dependencies
  5. Automate Protection: Use dependency scanning tools in your development workflow

File extraction vulnerabilities remain a persistent threat vector. By understanding how these attacks work and implementing robust security controls, you can significantly reduce your application's attack surface. Remember: security is not a one-time fix but an ongoing practice that requires vigilance, education, and proactive defense.

Secure your archives today—your users' systems depend on it.


For more information about this vulnerability, consult the official CVE database and the node-tar security advisories. Always follow responsible disclosure practices when discovering security issues.

Frequently Asked Questions

What is hardlink path traversal in tar extraction?

It's when an attacker crafts a tar archive with hardlink entries containing path traversal sequences (like `../`) that bypass security checks, allowing files to be extracted outside the intended extraction directory.

How do you prevent hardlink path traversal in Node.js?

Validate all hardlink targets by resolving them to absolute paths, verifying they remain within the extraction directory, and rejecting any attempts to escape directory boundaries using `path.resolve()` and `path.relative()`.

What CWE is hardlink path traversal?

CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal'), which covers directory escape vulnerabilities in file operations.

Is checking for `../` sequences enough to prevent this vulnerability?

No, simple string matching for `../` can be bypassed through symlinks, URL encoding, or other path normalization tricks. You must use proper path resolution functions that canonicalize paths before validation.

Can static analysis detect this vulnerability?

Yes, static analysis tools can identify missing path validation in tar extraction code, particularly when hardlink targets aren't verified against extraction boundaries before file operations.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #61

Related Articles

high

How missing Dependabot cooldown happens in GitHub Actions and how to fix it

A high-severity configuration vulnerability was discovered in a `.github/dependabot.yml` file that lacked a cooldown period for package updates. Without this safeguard, Dependabot could immediately propose updates to newly published package versions—including potentially malicious or unstable releases. The fix adds a simple `cooldown` block with a 7-day waiting period before any new package version is suggested.

high

How Server-Sent Events Injection via Unsanitized Newlines happens in Node.js h3 and how to fix it

A high-severity Server-Sent Events (SSE) injection vulnerability (CVE-2026-33128) was discovered in the h3 HTTP framework, where unsanitized newline characters in event stream fields could allow attackers to inject arbitrary SSE messages. The fix upgrades h3 from version 1.15.5 to 1.15.6 in the frontend's dependency tree, ensuring that newline characters are properly sanitized before being written to event streams.

high

How Memory Exhaustion via Large Comma-Separated Selector Lists happens in Python Soup Sieve and how to fix it

A high-severity memory exhaustion vulnerability (CVE-2026-49476) was discovered in Soup Sieve version 2.8.3, affecting Python applications that parse CSS selectors from user-controlled input. The vulnerability allows attackers to craft malicious selector lists that consume excessive memory, potentially causing denial of service. The fix involves upgrading to soupsieve 2.8.4, which implements proper resource limits on selector parsing.

high

How prototype pollution via `__proto__` key happens in Node.js defu and how to fix it

A high-severity prototype pollution vulnerability (CVE-2026-35209) was discovered in the `defu` package version 6.1.4, which allowed attackers to inject properties into JavaScript's `Object.prototype` via the `__proto__` key in defaults arguments. The fix upgrades `defu` to version 6.1.5 in the frontend's dependency tree, protecting downstream consumers like `c12` and `dotenv` configuration loaders from malicious property injection.

critical

How buffer overflow in memcpy() happens in Node.js N-API bindings and how to fix it

A critical buffer overflow vulnerability was discovered in the GetBufferAsVector() function in examples_nodejs/src/zupt_napi.cpp, where memcpy() copied data from JavaScript Uint8Array buffers without proper bounds validation. This vulnerability could allow attackers to trigger memory corruption by providing maliciously crafted input arrays to the native Node.js module, potentially leading to crashes or arbitrary code execution.

high

How memory exhaustion via large comma-separated selector lists happens in Python soupsieve and how to fix it

A high-severity memory exhaustion vulnerability (CVE-2026-49476) was discovered in soupsieve 2.8.3, a CSS selector library used by BeautifulSoup in Python. An attacker who could influence CSS selector input could craft large comma-separated selector lists to exhaust system memory, causing denial of service. The fix upgrades soupsieve from 2.8.3 to 2.8.4 in the backend's `uv.lock` dependency file.