A critical vulnerability in the tar npm package—versions 7.5.11 through 7.5.18—allows attackers to mount denial-of-service attacks using crafted gzip archives. These "gzip bombs" exploit the disparity between compressed and decompressed sizes: a few kilobytes of compressed data can expand to gigabytes, overwhelming memory and CPU resources during extraction. The fix, released in tar 7.5.19, introduces defensive limits on decompression ratios.
This issue is particularly insidious because it exploits a fundamental property of compression algorithms rather than a coding error. The tar package's automatic detection of gzip-compressed archives and its stream-based processing pipeline made it an ideal target for resource exhaustion attacks in CI/CD pipelines, package managers, and file upload handlers.
Affected Versions
| Affected | >= 7.5.11, <= 7.5.18 |
| Fixed in | 7.5.19 |
| Ecosystem | npm |
| CVE / GHSA | CVE-2026-59873 / not assigned |
| CWE | unknown |
The Vulnerability Explained
The tar package provides streaming archive extraction with automatic format detection. When encountering a .tar.gz file or gzip-compressed stream, it pipes input through zlib's Gunzip transform without enforcing upper bounds on the output-to-input size ratio.
An attacker crafts a small archive—perhaps 10KB compressed—that decompresses to 10GB or more. The classic pattern uses repeated identical data (like null bytes), achieving extreme compression ratios. When tar processes this:
// Vulnerable pattern in tar 7.5.11
// Automatic gzip detection triggers unbounded decompression
const tar = require('tar')
await tar.x({ file: 'archive.tar.gz', cwd: '/tmp' })
// Memory unbounded until OOM kill
The tar.x() function, along with tar.t() and stream constructors, all share this vulnerable decompression path. The file option and stream inputs both trigger automatic format detection, which instantiates a Gunzip stream without ratio checking.
Real-world impact is severe for services that accept user uploads or process third-party archives: container registries, package mirrors, build systems, and deployment pipelines. A single malicious upload can crash worker processes, trigger container restarts, or exhaust memory quotas in serverless environments.
The Fix
Version 7.5.19 introduces decompression guards by tracking the ratio between compressed bytes read and uncompressed bytes produced. When this ratio exceeds a safe threshold, tar throws a TAR_BAD_ARCHIVE error and terminates processing.
The upgrade changes the overrides entry in package.json:
- "tar": "7.5.11",
+ "tar": "7.5.21",
And correspondingly in the lockfile:
- tar@7.5.11:
- resolution: {integrity: sha512-Chj...}
+ tar@7.5.21:
+ resolution: {integrity: sha512-Xdht...}
engines: {node: '>=18'}
The fix works by instrumenting the gzip decompression stream with byte counters. Before yielding each chunk of decompressed data, tar compares cumulative output against cumulative input. If outputBytes > inputBytes * MAX_RATIO (with a conservative default), processing halts immediately.
This approach preserves streaming efficiency for legitimate archives while bounding worst-case resource consumption. The error is catchable, allowing applications to log and reject malicious uploads gracefully rather than crashing.
Key Takeaways
-
Automatic format detection is a double-edged sword:
tar's seamless handling of.tar.gz,.tar.bz2, and compressed streams improves developer experience but creates implicit trust boundaries that attackers can exploit. -
Compression ratios must have configurable caps: Any system accepting compressed input from untrusted sources should enforce maximum expansion ratios. The tar 7.5.19 default of approximately 100:1 accommodates virtually all legitimate use cases.
-
Stream processing doesn't imply unbounded processing: Even stream-based APIs can exhaust resources if they lack backpressure and ratio limits. The vulnerability existed in streaming code, not synchronous buffering.
-
Dependency overrides require active maintenance: This fix arrived through a manual
overridesentry inpackage.json, not a direct dependency. Transitive dependency trees hide vulnerable versions; explicit overrides need periodic review.
How Orbis AppSec Detected This
Source: The file parameter passed to tar.x() or tar.t() functions, or any readable stream piped to tar's extract transform.
Sink: The internal Gunzip stream instantiation in tar's Parse class, invoked when magic bytes indicate gzip compression.
Missing control: No validation of decompression ratio before or during the transformation; no maxReadSize or similar option enforced during automatic format detection.
CWE: unknown
Fix: Upgraded tar from 7.5.11 to 7.5.19, which adds automatic decompression ratio limits that throw catchable errors on gzip bomb detection.
Orbis AppSec detected this vulnerability automatically. Try Orbis AppSec on your repositories to find and fix issues like this.
Conclusion
CVE-2026-59873 demonstrates how compression algorithms, when used without safeguards, become attack vectors for resource exhaustion. The tar package's automatic gzip handling—normally a convenience feature—became a liability when confronted with pathological inputs. The 7.5.19 fix restores safety without sacrificing the streaming API's ergonomics, but it serves as a reminder that any system accepting compressed data from external sources must implement defense-in-depth through ratio limits, memory caps, and processing timeouts.