Introduction
In the cc-viewer application, Trivy scanner flagged a high-severity vulnerability in the project's package-lock.json file: the application was using adm-zip version 0.5.17, which contains CVE-2026-39244—a Denial of Service vulnerability that allows attackers to crash the application through specially crafted ZIP files. The vulnerable dependency was declared in package.json at line 123 with "adm-zip": "^0.5.17", exposing any code path that processes ZIP archives to potential memory exhaustion attacks.
This vulnerability is particularly concerning for cc-viewer because the application processes session transcripts, and if those transcripts are delivered in ZIP format, an attacker could submit a malicious archive that appears to be a few kilobytes but decompresses to gigabytes or terabytes of data. The result? Complete memory exhaustion and application crash.
The Vulnerability Explained
CVE-2026-39244 is a classic ZIP bomb vulnerability in adm-zip versions prior to 0.6.0. A ZIP bomb (also known as a decompression bomb) is a malicious archive file designed to crash or render useless the program or system reading it.
Here's how the attack works with adm-zip 0.5.17:
The Vulnerable Code Pattern
When cc-viewer's code uses adm-zip to extract archives:
const AdmZip = require('adm-zip');
const zip = new AdmZip(uploadedFile);
zip.extractAllTo(targetDirectory); // Vulnerable in 0.5.17
The library in version 0.5.17 lacks critical safeguards:
- No decompression ratio checks: It doesn't verify that a 10KB file isn't trying to expand to 10GB
- No expanded size limits: It will attempt to decompress files of any size into memory
- No recursive compression detection: It won't catch nested ZIP files designed to multiply the expansion effect
Real-World Attack Scenario
An attacker targeting cc-viewer could:
- Create a malicious ZIP file using recursive compression (a ZIP file containing ZIP files, nested multiple levels deep)
- The outer archive might be only 42KB in size
- Upload this file to any endpoint that processes ZIP archives in cc-viewer
- When adm-zip 0.5.17 attempts to extract it, each layer expands exponentially
- A carefully crafted file can expand from 42KB to 4.5 petabytes
- Node.js process runs out of memory and crashes
- The application becomes unavailable (Denial of Service)
The famous "42.zip" file demonstrates this perfectly: 42 kilobytes compressed, 4.5 petabytes uncompressed—a compression ratio of over 100 million to 1.
Impact on cc-viewer
Given that cc-viewer processes session transcripts (as evidenced by server/lib/session-transcript-reader.js), if the application accepts ZIP-compressed transcripts from users or external systems, an attacker could:
- Crash the server by uploading a ZIP bomb
- Cause repeated crashes if the malicious file is stored and reprocessed
- Create a persistent Denial of Service condition
- Potentially affect other users if the service becomes unavailable
The Fix
The fix is straightforward but critical: upgrade adm-zip from version 0.5.17 to 0.6.0.
Before (Vulnerable):
package.json:
{
"dependencies": {
"adm-zip": "^0.5.17"
}
}
package-lock.json:
{
"node_modules/adm-zip": {
"version": "0.5.17",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.17.tgz",
"integrity": "sha512-+Ut8d9LLqwEvHHJl1+PIHqoyDxFgVN847JTVM3Izi3xHDWPE4UtzzXysMZQs64DMcrJfBeS/uoEP4AD3HQHnQQ==",
"engines": {
"node": ">=12.0"
}
}
}
After (Fixed):
package.json:
{
"dependencies": {
"adm-zip": "^0.6.0"
}
}
package-lock.json:
{
"node_modules/adm-zip": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.6.0.tgz",
"integrity": "sha512-XleryMhbuksdKtofnWZ9Sk+4CUTbms4Mb/EU32SZwToAyZ5RgVos/ki8n+yr0LWHOGKuakbXTuuYNHLQjhddgg==",
"engines": {
"node": ">=14.0"
}
}
}
What Changed in adm-zip 0.6.0
The adm-zip maintainers implemented several critical security improvements in version 0.6.0:
- Decompression ratio limits: The library now monitors the ratio between compressed and uncompressed sizes
- Maximum expanded size checks: Configurable limits prevent extraction of files beyond a certain size
- Recursive compression detection: The library can detect and reject nested ZIP files designed to multiply expansion
- Memory allocation safeguards: Better memory management prevents runaway allocation during extraction
- Enhanced validation: Additional checks on ZIP file structure to detect malformed or malicious archives
These changes mean that when cc-viewer processes a ZIP file with the updated library, adm-zip 0.6.0 will:
- Reject files with suspicious compression ratios before attempting extraction
- Stop extraction if the uncompressed size exceeds safe limits
- Detect and block recursive ZIP bombs
- Fail safely without crashing the application
Why Both Files Changed
The fix required updates to both package.json and package-lock.json:
- package.json (line 123): Updated the dependency declaration from
"adm-zip": "^0.5.17"to"adm-zip": "^0.6.0"to specify the minimum safe version - package-lock.json (lines 5447-5453): Updated the resolved version, integrity hash, and Node.js engine requirement from
>=12.0to>=14.0to match the new library's requirements
The version bump in package.json from 1.7.21 to 1.7.22 properly semantically versions this security fix as a patch release.
Prevention & Best Practices
To avoid ZIP bomb vulnerabilities in your Node.js applications:
1. Keep Dependencies Updated
Regularly audit and update your dependencies:
npm audit
npm update
Use tools like Dependabot, Renovate, or Trivy to automatically detect vulnerable dependencies.
2. Implement Application-Level Safeguards
Even with a secure library, add additional protections:
const AdmZip = require('adm-zip');
const fs = require('fs');
function safeExtract(zipPath, targetDir) {
// Check file size before processing
const stats = fs.statSync(zipPath);
const MAX_SIZE = 100 * 1024 * 1024; // 100MB limit
if (stats.size > MAX_SIZE) {
throw new Error('ZIP file too large');
}
const zip = new AdmZip(zipPath);
const entries = zip.getEntries();
// Check total uncompressed size
let totalSize = 0;
for (const entry of entries) {
totalSize += entry.header.size;
if (totalSize > MAX_SIZE * 10) { // Max 10x expansion
throw new Error('Suspicious compression ratio detected');
}
}
zip.extractAllTo(targetDir);
}
3. Use Security Headers and Limits
Configure your application with resource limits:
- Set maximum upload file sizes
- Implement request timeouts
- Use memory limits for Node.js processes (--max-old-space-size)
- Run in containerized environments with resource constraints
4. Validate Archive Contents
Before extraction:
- Check file count limits
- Validate file paths for directory traversal attempts
- Scan for suspicious patterns (deeply nested structures)
- Verify expected file types
5. Monitor and Alert
Implement monitoring for:
- Unusual memory consumption patterns
- Slow extraction operations
- Repeated extraction failures
- Process crashes
6. Security Standards Alignment
This vulnerability maps to:
- CWE-400: Uncontrolled Resource Consumption
- OWASP Top 10 2021 - A05:2021: Security Misconfiguration (using vulnerable components)
Follow OWASP guidelines for secure file upload and processing.
Key Takeaways
- adm-zip 0.5.17 has no protection against ZIP bombs: The library would attempt to decompress malicious archives without checking expansion ratios, leading to memory exhaustion in cc-viewer
- CVE-2026-39244 is exploitable with minimal effort: Attackers can use publicly available ZIP bomb files (like 42.zip) or create custom ones to crash applications processing user-uploaded archives
- The package-lock.json integrity hash change is critical: The update from
sha512-+Ut8d9LLqw...tosha512-XleryMhbuk...ensures npm installs the secure version, not a compromised package - Node.js version requirement increased: adm-zip 0.6.0 requires Node.js >=14.0 (up from >=12.0), so verify your runtime environment supports this before deploying
- Session transcript processing in cc-viewer is now protected: Any code path using adm-zip to extract archives—particularly in
server/lib/session-transcript-reader.js—is now safe from decompression bomb attacks
How Orbis AppSec Detected This
- Source: The vulnerable dependency was declared in
package.jsonat line 123 and resolved inpackage-lock.jsonat line 5447 - Sink: Any code path in cc-viewer that uses
adm-zipto process ZIP archives, particularly methods likeextractAllTo()orgetEntries()that trigger decompression - Missing control: adm-zip 0.5.17 lacked decompression ratio validation, expanded size limits, and recursive compression detection
- CWE: CWE-400 (Uncontrolled Resource Consumption)
- Fix: Upgraded adm-zip from 0.5.17 to 0.6.0, which implements comprehensive ZIP bomb protections including ratio checks and memory safeguards
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-39244 in adm-zip demonstrates how a seemingly simple dependency can expose your entire application to Denial of Service attacks. The cc-viewer application's upgrade from adm-zip 0.5.17 to 0.6.0 eliminates the risk of ZIP bomb attacks that could crash the server and disrupt service for all users.
This fix highlights the importance of proactive dependency management and automated security scanning. A vulnerability in a single library can have cascading effects across your entire application, especially when that library handles untrusted input like file uploads.
Always keep your dependencies updated, implement defense-in-depth with application-level validation, and use automated tools to catch vulnerabilities before they reach production. The few minutes spent upgrading a package can prevent hours of incident response and potential data loss or service disruption.