Back to Blog
critical SEVERITY5 min read

How Denial of Service via gzip bomb happens in Node.js tar and how to fix it

A critical Denial of Service vulnerability (CVE-2026-59873) was discovered in the node-tar package where attackers could craft malicious gzip archives that expand to consume all available system resources. This vulnerability affected version 7.5.15 of the tar package and was fixed by upgrading to version 7.5.19. The fix protects applications from resource exhaustion attacks when processing untrusted archive files.

O
By Orbis AppSec
Published July 28, 2026Reviewed July 28, 2026

Answer Summary

CVE-2026-59873 is a critical Denial of Service vulnerability in the Node.js `tar` package (node-tar) that allows attackers to crash applications using crafted gzip bomb archives. This is classified as a resource exhaustion attack where a small compressed file expands to consume excessive memory or disk space. The fix requires upgrading the `tar` dependency from version 7.5.15 to 7.5.19, which implements proper decompression limits and resource controls.

Vulnerability at a Glance

cweCWE-409 (Improper Handling of Highly Compressed Data)
fixUpgrade tar package from 7.5.15 to 7.5.19
riskCritical - Application crash and resource exhaustion
languageNode.js / JavaScript
root causeInsufficient validation of compressed archive expansion ratios
vulnerabilityDenial of Service via gzip bomb

Introduction

In the Acode project's bun.lock file, Trivy detected a critical vulnerability in the tar package at version 7.5.15. This wasn't just a theoretical concern—the application uses tar for handling archive operations, and the vulnerable version lacked proper safeguards against a particularly nasty attack vector: gzip bombs.

The tar package is a fundamental dependency in the Node.js ecosystem, used by countless applications for archive extraction. When this library fails to properly validate decompression ratios, it opens the door for attackers to craft archives that appear innocuous but expand to consume gigabytes of memory in seconds.

Looking at the bun.lock file, we can see the application has numerous Cordova plugins and dependencies that rely on archive handling:

"cordova-plugin-advanced-http": "file:src/plugins/cordova-plugin-advanced-http",
"cordova-plugin-browser": "file:src/plugins/browser",

Any of these plugin installations or updates could potentially process untrusted archive data, making this vulnerability particularly dangerous in a mobile development context.

The Vulnerability Explained

What is a Gzip Bomb?

A gzip bomb (also known as a zip bomb or decompression bomb) exploits the fundamental nature of compression algorithms. Compression works by finding patterns and redundancies in data—a file containing millions of repeated zeros compresses extremely well but expands back to its full size when decompressed.

Here's what makes this attack devastating:

  1. Asymmetric resource consumption: A 1KB compressed file could expand to 1GB or more
  2. Legitimate appearance: The archive passes basic validation checks
  3. Rapid resource exhaustion: Memory fills before the application can react

The Attack Scenario

Consider this attack flow against the vulnerable Acode application:

  1. An attacker crafts a malicious .tar.gz file containing nested layers of compression
  2. The file is only 42KB compressed but expands to 4.5GB
  3. A user attempts to install a plugin or extract an archive containing this bomb
  4. The tar@7.5.15 package begins decompression without ratio limits
  5. Node.js allocates memory as fast as it can decompress
  6. The application crashes with an out-of-memory error, or worse, the entire system becomes unresponsive

The vulnerable code path in tar 7.5.15 lacked checks like:

// Missing in 7.5.15 - No decompression ratio validation
// The library would blindly decompress without limits
const extract = tar.extract({
  // No maxSize option
  // No ratio checking
});

Real-World Impact

For the Acode project specifically, this vulnerability is particularly concerning because:

  • Mobile context: Mobile devices have limited memory, making them more susceptible to resource exhaustion
  • Plugin ecosystem: The application loads plugins from external sources, creating a potential attack vector
  • User trust: Users expect plugin installations to be safe operations

The Fix

The fix was straightforward but critical—upgrading the tar dependency from version 7.5.15 to 7.5.19. Let's examine the actual changes in the bun.lock file:

Before (Vulnerable)

The bun.lock file didn't explicitly pin the tar version, relying on whatever version was resolved by the dependency tree.

After (Fixed)

"@codemirror/search": "^6.7.1",
"@codemirror/state": "^6.6.0",
"@codemirror/view": "^6.43.4",
"tar": "^7.5.19",  // Explicitly added with fixed version

The key changes in the diff show:

  1. Explicit dependency declaration: Adding "tar": "^7.5.19" to the dependencies ensures the fixed version is used
  2. Lock file update: The bun.lock file now pins the secure version across all installations

What Version 7.5.19 Fixes

The patched version implements several protective measures:

  • Decompression ratio limits: Rejects archives with suspiciously high compression ratios
  • Maximum output size: Configurable limits on extracted content size
  • Progressive validation: Checks ratios during extraction, not just at the end
  • Memory-aware extraction: Better handling of memory pressure during decompression

Prevention & Best Practices

1. Keep Dependencies Updated

Use automated tools to monitor for vulnerable dependencies:

# Using npm audit
npm audit

# Using Trivy (as used in this detection)
trivy fs --scanners vuln .

2. Implement Defense in Depth

Even with patched libraries, add application-level protections:

const tar = require('tar');

// Set explicit limits when extracting
tar.extract({
  file: 'archive.tar.gz',
  cwd: '/safe/directory',
  maxReadSize: 64 * 1024 * 1024,  // 64MB max
  filter: (path, entry) => {
    // Reject suspiciously large entries
    if (entry.size > 100 * 1024 * 1024) {
      return false;
    }
    return true;
  }
});

3. Validate Before Processing

For untrusted archives, perform preliminary checks:

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

function checkCompressionRatio(filePath, maxRatio = 100) {
  const compressedSize = fs.statSync(filePath).size;
  // Implement streaming check of uncompressed size
  // Reject if ratio exceeds threshold
}

4. Use Resource Limits

In production environments, implement OS-level protections:

// Set memory limits for the Node.js process
// node --max-old-space-size=512 app.js

// Or use container limits in Docker/Kubernetes

Key Takeaways

  • The tar@7.5.15 package in bun.lock was vulnerable to CVE-2026-59873, allowing denial of service through crafted gzip bombs
  • Explicit dependency pinning (adding "tar": "^7.5.19" directly) ensures the fixed version is used regardless of transitive dependency resolution
  • Mobile applications like Acode are especially vulnerable to resource exhaustion attacks due to limited device memory
  • Plugin ecosystems create attack surfaces—any code path that processes external archives needs protection
  • Automated scanning with Trivy caught this vulnerability before it could be exploited in production

How Orbis AppSec Detected This

  • Source: External archive files processed through the tar library, potentially from plugin installations or user-uploaded content
  • Sink: tar.extract() and related decompression functions in node-tar@7.5.15
  • Missing control: Decompression ratio validation and maximum output size limits were absent in the vulnerable version
  • CWE: CWE-409 (Improper Handling of Highly Compressed Data)
  • Fix: Upgraded tar dependency from 7.5.15 to 7.5.19 by adding explicit version constraint in bun.lock

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-59873 demonstrates why dependency management is a critical security practice. A single outdated package—tar@7.5.15—exposed the entire application to denial of service attacks through crafted gzip bombs. The fix was simple: upgrade to version 7.5.19 and explicitly declare the dependency.

For developers working with archive handling in Node.js:

  1. Always use the latest patched versions of archive libraries
  2. Implement application-level size and ratio limits as defense in depth
  3. Use automated scanning tools to catch vulnerable dependencies early
  4. Be especially cautious when processing archives from untrusted sources

The gzip bomb attack vector has been known for decades, but it continues to affect modern applications when libraries don't implement proper safeguards. Stay vigilant, keep your dependencies updated, and always assume untrusted input is malicious.

References

Frequently Asked Questions

What is a gzip bomb attack?

A gzip bomb is a malicious compressed archive designed to expand to an enormous size when decompressed, exhausting system memory or disk space and causing denial of service.

How do you prevent gzip bomb attacks in Node.js?

Use updated archive libraries that implement decompression ratio limits, set maximum output size thresholds, and validate archive contents before full extraction.

What CWE is gzip bomb vulnerability?

CWE-409 (Improper Handling of Highly Compressed Data) covers vulnerabilities where applications fail to properly handle archives with extreme compression ratios.

Is file size validation enough to prevent gzip bombs?

No, checking compressed file size alone is insufficient because gzip bombs are specifically designed to be small when compressed but expand to massive sizes during decompression.

Can static analysis detect gzip bomb vulnerabilities?

Yes, static analysis tools like Trivy can detect vulnerable versions of archive-handling libraries and flag them for upgrade, as demonstrated in this CVE-2026-59873 detection.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #2544

Related Articles

high

How Quadratic CPU Consumption Vulnerabilities Happen in JavaScript YAML Parsers and How to Fix Them

A high-severity denial-of-service vulnerability in js-yaml versions 3.x and 4.x allowed attackers to trigger quadratic CPU consumption through specially crafted YAML documents using the !!omap tag. This fix upgrades js-yaml from 4.1.1 to 4.3.1 and from 3.14.2 to 3.15.1, eliminating the algorithmic complexity attack vector that could freeze Node.js applications processing untrusted YAML input.

high

How javascript.lang.security.detect-child-process.detect-child-process happens in Node.js and how to fix it

A high-severity command injection vulnerability was discovered in `scripts/build.js` where `execSync` was called with string-interpolated arguments (`sourceDir` and `outputPath`) inside a shell command. By replacing `execSync` with `spawnSync` using an argument array (no shell), the fix eliminates the possibility of shell metacharacter injection while preserving identical build behavior.

high

How Command Injection happens in Node.js child_process and how to fix it

A command injection vulnerability in nix.js's Release class allowed potentially malicious input through the `arch` parameter to be executed via shell commands. The fix replaced `execSync()` with `execFileSync()`, eliminating shell interpretation and preventing command injection by passing arguments as an array instead of a concatenated string.

critical

How Sensitive Data Exposure in Error Logging happens in TypeScript/Deno and how to fix it

A critical vulnerability in Supabase Edge Functions allowed sensitive authentication errors and API credentials to leak through verbose error logging. The `cancel-subscription/index.ts` function logged full error objects to the console, potentially exposing Paddle API keys and auth tokens in deployment logs. The fix sanitizes all error messages to log only safe error text while preserving debugging capability.

critical

How HTTP Header Injection Happens in Go and How to Fix It

A critical vulnerability in the file upload handler allowed attackers to inject CRLF sequences into HTTP response headers through crafted filenames. The fix sanitizes user-supplied filenames before using them in Content-Disposition headers, preventing header injection attacks that could lead to cache poisoning, session fixation, or XSS.

high

How Path Traversal and Security Policy Bypass Happens in Node.js Dependencies and How to Fix It

A high-severity vulnerability in the fast-uri package (CVE-2026-6321) allowed attackers to bypass security policies through improper Unicode hostname canonicalization and path traversal. This issue affected the @apralabs/apra-fleet project through its dependency tree, and was resolved by upgrading fast-uri from version 3.1.0 to 4.1.2 using npm overrides.