How Denial of Service via Crafted Long-Path Tar Archives Happens in Node.js and How to Fix It
Introduction
In applications using the tar package for Node.js, a critical vulnerability lurked in how the library processed file paths within tar archives. CVE-2026-73566 represents a real-world Denial of Service threat: attackers could craft malicious tar files containing paths of extreme length that would cause the application to consume excessive memory and CPU resources, ultimately crashing the service.
The vulnerability was discovered in package-lock.json as a dependency of the tar package at version 7.5.19. When applications extract or validate tar archives without proper constraints on path lengths, a single malformed archive could bring down production services. This wasn't a theoretical risk—it was a concrete attack surface that needed immediate patching.
The Vulnerability Explained
What Makes This Attack Possible?
The tar package in Node.js is responsible for reading, parsing, and extracting tar archive files. Tar files contain a series of file entries, each with metadata including file path, permissions, size, and content. In versions 7.5.19 and earlier, the library did not adequately validate or limit the length of file paths during parsing.
Here's the attack scenario:
- Attacker creates a crafted tar archive with a file entry whose path string is thousands or millions of characters long
- Application receives and processes the archive using
tar.extract()or similar methods - Parser allocates memory for each path string without reasonable limits
- Resource exhaustion occurs: Memory fills up, string operations become increasingly slow, CPU usage spikes
- Application becomes unresponsive or crashes entirely
The vulnerability falls under CWE-400: Uncontrolled Resource Consumption. The tar parser was treating untrusted input (file paths in archives) without implementing resource quotas or sanity checks.
The Real-World Impact
Consider a file upload service that accepts tar archives for batch processing:
// Vulnerable code pattern (before fix)
const tar = require('tar');
const fs = require('fs');
app.post('/upload-archive', (req, res) => {
const uploadedFile = req.files.archive;
// Extract without path length validation
tar.extract({
file: uploadedFile.path,
cwd: '/tmp/extract'
}).then(() => {
res.send('Archive extracted successfully');
}).catch(err => {
res.status(500).send('Extraction failed');
});
});
An attacker could upload a tar file with a single entry like:
entry_name: AAAA...AAAA (10,000,000 characters)
entry_size: 0
When the parser processes this, it attempts to allocate a string buffer for this impossibly long path. On a server handling multiple concurrent requests, this could trigger:
- Memory exhaustion: Each malicious archive consumes gigabytes of RAM
- Garbage collection pauses: The JavaScript engine struggles to clean up massive strings
- Complete service unavailability: Other legitimate requests timeout
The Fix
The fix involved upgrading the tar package from version 7.5.19 to 7.5.21. Let's examine the changes:
Package Version Update
Before (Vulnerable):
"node_modules/tar": {
"version": "7.5.19",
"resolved": "https://registry.npmmirror.com/tar/-/tar-7.5.19.tgz",
"integrity": "sha512-4LeEWl96twnS2Q7Bz4MGqgazLqO+hJN63GZxXoIqh1T3VweYD997gbU1ItNsQafqqXTXd5WFyFdReLtwvRBNiw=="
}
After (Patched):
"node_modules/tar": {
"version": "7.5.21",
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.21.tgz",
"integrity": "sha512-XdhtCvlMywwxpCW8YEq3lOXBJpUPTR2OHHcwLPO3HwsJqOHa2Ok/oJ7ruGzp+JrKoRPVCzJwAdEjqLW/vNRPHA=="
}
The version bump from 7.5.19 to 7.5.21 includes two minor versions of patches. Between these versions, the tar maintainers implemented critical path length validation.
Dependency Override Addition
Additionally, package.json was updated to include an explicit override:
Before:
{
"dependencies": {
"tar": "^7.5.19"
}
}
After:
{
"dependencies": {
"tar": "^7.5.19"
},
"overrides": {
"tar": "7.5.21"
}
}
This override ensures that even if other dependencies specify older versions of tar, the project will always use 7.5.21. This is crucial because transitive dependencies might have pinned tar to earlier vulnerable versions.
What Changed in tar 7.5.21?
While the exact implementation details are in the tar repository, version 7.5.21 introduces:
- Path length validation: File paths are now checked against a reasonable maximum length (typically 4096 bytes for filesystem compatibility)
- Early rejection: Archives with excessively long paths are rejected during parsing rather than attempting to process them
- Resource consumption guards: The parser implements limits on memory allocation per entry
- Error handling: Clear error messages when malformed entries are encountered
Secure Code After Fix
With the patched version, the same code becomes safe:
// Safe code after fix (tar 7.5.21)
const tar = require('tar');
const fs = require('fs');
app.post('/upload-archive', (req, res) => {
const uploadedFile = req.files.archive;
// Extract now validates path lengths internally
tar.extract({
file: uploadedFile.path,
cwd: '/tmp/extract'
}).then(() => {
res.send('Archive extracted successfully');
}).catch(err => {
// Will catch malformed archives with long paths
if (err.message.includes('path')) {
res.status(400).send('Invalid archive: path length exceeded');
} else {
res.status(500).send('Extraction failed');
}
});
});
Now, when an attacker uploads a crafted archive with a 10-million-character path, the parser immediately rejects it with an error rather than attempting to process it.
Prevention & Best Practices
1. Keep Dependencies Updated
The most effective defense is staying current with security patches:
# Check for vulnerabilities
npm audit
# Update to patched versions
npm update tar
# Verify the fix
npm list tar
2. Implement Additional Validation
Even with patched libraries, defense-in-depth is important:
const tar = require('tar');
const path = require('path');
// Custom validation wrapper
async function safeExtractTar(archivePath, targetDir) {
// Validate archive file size first
const stats = fs.statSync(archivePath);
const MAX_ARCHIVE_SIZE = 100 * 1024 * 1024; // 100MB
if (stats.size > MAX_ARCHIVE_SIZE) {
throw new Error('Archive exceeds maximum size');
}
// Extract with timeout
return Promise.race([
tar.extract({
file: archivePath,
cwd: targetDir,
strict: true // Reject invalid tar entries
}),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Extraction timeout')), 30000)
)
]);
}
3. Use Security Scanners
Integrate vulnerability scanning into your CI/CD pipeline:
# Using Trivy (which detected this vulnerability)
trivy fs .
# Using npm audit
npm audit --audit-level=high
# Using Snyk
snyk test
4. Sandbox Untrusted Archives
Process untrusted archives in isolated environments:
const { spawn } = require('child_process');
// Extract in a separate process with resource limits
function extractInSandbox(archivePath, targetDir) {
return new Promise((resolve, reject) => {
const proc = spawn('tar', ['-xf', archivePath, '-C', targetDir], {
timeout: 30000,
maxBuffer: 1024 * 1024 // 1MB buffer limit
});
proc.on('close', (code) => {
if (code === 0) resolve();
else reject(new Error(`tar exited with code ${code}`));
});
proc.on('error', reject);
});
}
5. Monitor Resource Usage
Implement monitoring for extraction operations:
const tar = require('tar');
const os = require('os');
async function monitoredExtract(archivePath, targetDir) {
const initialMemory = process.memoryUsage().heapUsed;
const startTime = Date.now();
try {
await tar.extract({
file: archivePath,
cwd: targetDir
});
const memoryDelta = process.memoryUsage().heapUsed - initialMemory;
const duration = Date.now() - startTime;
// Alert if extraction consumed excessive resources
if (memoryDelta > 50 * 1024 * 1024) { // 50MB
console.warn('High memory consumption during extraction:', memoryDelta);
}
if (duration > 10000) { // 10 seconds
console.warn('Slow extraction detected:', duration);
}
} catch (err) {
console.error('Extraction failed:', err.message);
throw err;
}
}
Key Takeaways
- Never assume tar files are well-formed: Always validate archive structure and path lengths, even with updated libraries
- Path length validation is critical: The 7.5.21 fix adds explicit checks that reject archives with paths exceeding filesystem limits
- Use explicit version overrides: The
"overrides"field in package.json ensures transitive dependencies don't pull in vulnerable versions - Implement defense-in-depth: Combine library updates with timeouts, size limits, and sandboxing for untrusted archives
- Monitor extraction operations: Resource consumption during tar processing can indicate attack attempts or malformed files
How Orbis AppSec Detected This
Source: Dependency scanning of package-lock.json identified the tar package at version 7.5.19
Sink: The tar.extract() method in version 7.5.19 processes file path entries from untrusted tar archives without validating path length
Missing control: Absence of path length validation and resource consumption limits in the tar parser, allowing attackers to craft archives that exhaust system memory
CWE: CWE-400: Uncontrolled Resource Consumption ('Resource Exhaustion')
Fix: Upgrade tar package from 7.5.19 to 7.5.21, which implements path length validation and rejects archives with excessively long file paths
Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.
Conclusion
CVE-2026-73566 demonstrates how even well-maintained open-source libraries can have resource consumption vulnerabilities when processing untrusted input. The fix—upgrading tar to 7.5.21—is straightforward, but the lesson is broader: always validate the structure and constraints of data you process, especially when it comes from external sources.
By combining timely dependency updates, explicit version overrides, additional validation layers, and resource monitoring, you can protect your applications from similar DoS attacks. The security community's rapid response in patching tar shows the importance of staying engaged with security advisories and maintaining up-to-date dependencies.
For teams managing large Node.js applications, this vulnerability serves as a reminder to:
- Automate dependency scanning in CI/CD pipelines
- Establish clear policies for responding to HIGH and CRITICAL vulnerabilities
- Test archive extraction with both valid and malformed inputs
- Document resource limits for operations processing untrusted data
Stay secure, keep your dependencies patched, and validate early and often.