adm-zip (npm), Decompression Resource Exhaustion Bypass, CVE-2026-39244 -DC-Sep2026-2612

Listen to this Post

CVE-2026-39244 affects adm-zip version 0.6.0.

The package is used to read, write, and extract ZIP archives in Node.js.

The original fix added maxOutputLength to zlib.inflateRawSync.

The limit was set to expectedLength.

expectedLength comes from the ZIP entry uncompressed-size header.

The fields are CENLEN and LOCLEN.

They are 4-byte little-endian values.

An attacker controls these header fields inside a crafted ZIP.
The fix only applies the cap when expectedLength > 0.

The code path uses:

const option = version >= 15 && expectedLength > 0 ? { maxOutputLength: expectedLength } : {};

return zlib.inflateRawSync(inbuf, option);

If expectedLength is exactly 0, the condition is false.

Then option becomes an empty object.

No maxOutputLength is passed to zlib.

Node falls back to zlib’s internal default limit.

That default can be several GB.

A small DEFLATE payload can expand greatly.

Raw DEFLATE can approach about 1032:1 compression.

A few MB can become multi-GB in memory.

CRC32 validation still passes.

CRC is computed over real decompressed output.

CRC is not computed over the declared size.

The local file header and central directory both store the size.

Both copies can be patched to 0.

The compressed bytes remain unchanged.

The archive remains structurally valid.

Loading with new AdmZip(buffer) reaches the same inflater code.

Calling getEntries()

.getData() triggers decompression.</h2>

<h2 class="f1b-anim" style="color:#3b82f6;border-left:4px solid #3b82f6;padding-left:12px;margin:22px 0 10px 0;font-weight:bold">readFile, readAsText, and extractAllTo share this code path.</h2>

With declared size 0, decompression succeeds without the intended cap.
With a small nonzero declared size, the cap works and throws.

<h2 class="f1b-anim" style="color:#3b82f6;border-left:4px solid #3b82f6;padding-left:12px;margin:22px 0 10px 0;font-weight:bold">This is a resource-exhaustion bypass.</h2>

<h2 class="f1b-anim" style="color:#3b82f6;border-left:4px solid #3b82f6;padding-left:12px;margin:22px 0 10px 0;font-weight:bold">It can cause process crash or OOM.</h2>

<h2 class="f1b-anim" style="color:#3b82f6;border-left:4px solid #3b82f6;padding-left:12px;margin:22px 0 10px 0;font-weight:bold">DailyCVE Form:</h2>

Platform: adm-zip (npm)
Version: 0.6.0
Vulnerability: Decompression cap bypass
Severity: Unspecified
date: Unknown

<h2 class="f1b-anim" style="color:#3b82f6;border-left:4px solid #3b82f6;padding-left:12px;margin:22px 0 10px 0;font-weight:bold">Prediction: Patch date unknown</h2>

<h2 class="f1b-anim" style="color:#3b82f6;border-left:4px solid #3b82f6;padding-left:12px;margin:22px 0 10px 0;font-weight:bold">(end of form)</h2>

<h2 class="f1b-anim" style="color:#3b82f6;border-left:4px solid #3b82f6;padding-left:12px;margin:22px 0 10px 0;font-weight:bold">What Undercode Say:</h2>

[bash]
npm ls adm-zip
npm install [email protected]
node admzip-bypass-poc.js
// methods/inflater.js
const option = version >= 15 && expectedLength > 0 ? { maxOutputLength: expectedLength } : {};
return zlib.inflateRawSync(inbuf, option);
const AdmZip = require('adm-zip');
const zip = new AdmZip(buffer);
const data = zip.getEntries()[bash].getData();
console.log(data.length);
// Control: declared size = 1024 -> throws Cannot create a Buffer larger than N bytes
// Bypass: declared size = 0 -> returns full 4,194,304-byte buffer
// Verified reproducible across 3 independent runs

Exploit: (Educational Purposes!)

// Build ZIP with one DEFLATE entry.
// Real content is highly redundant.
// Patch local header LOCLEN to 0.
// Patch central directory CENLEN to 0.
// Keep compressed bytes unchanged.
// Keep CRC32 unchanged.
// Load with adm-zip 0.6.0.
// Call getData(), readFile(), readAsText(), or extractAllTo().
// Result: full decompressed buffer without intended maxOutputLength cap.

Protection: from this CVE

Upgrade adm-zip.

Apply maxOutputLength unconditionally.

Set absolute output ceiling.

Add compression-ratio check.

Reject zero declared size.

Limit upload size.

Use worker memory limits.

Monitor extraction memory.

Impact:

Any application reading untrusted ZIP files can allocate memory bounded only by zlib internal default. A small upload can trigger multi-GB memory consumption. Process crash or OOM is possible. Upload handlers, CI artifact extraction, and email attachment scanning are exposed.

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top