adm-zip
Ecosystem: npm
Downloads:
- 0CriticalAffects 0 versions
- 5HighAffects 5 versions
- 0MediumAffects 0 versions
- 4ModerateAffects 4 versions
- 0LowAffects 0 versions
- Critical0 (0.0%)
- High5 (55.6%)
- Medium0 (0.0%)
- Moderate4 (44.4%)
- Low0 (0.0%)
Monthly breakdown
- Critical
- High
- Medium
- Moderate
- Low
- 6 vulnerabilities
- Critical: 0
- High: 4
- Medium: 0
- Moderate: 2
- Low: 0
- 1 vulnerabilities
- Critical: 0
- High: 0
- Medium: 0
- Moderate: 1
- Low: 0
- 1 vulnerabilities
- Critical: 0
- High: 1
- Medium: 0
- Moderate: 0
- Low: 0
- 1 vulnerabilities
- Critical: 0
- High: 0
- Medium: 0
- Moderate: 1
- Low: 0
Vulnerabilities (9)
Known vulnerabilities affecting adm-zip, based on data from OSV.
| ID | Severity | Summary | Affected versions | Published | Source |
|---|---|---|---|---|---|
| GHSA-8238-w5pm-2374 | High | adm-zip: Unhandled error event in async DEFLATE decompression crashes Node.js process (DoS)## Summary Denial of Service in `adm-zip`'s async decompression API allows an unauthenticated attacker to crash the entire Node.js host process by supplying a single malformed ZIP file. ## Details **Affected package**: adm-zip **Affected versions**: at least 0.6.0 (current latest); likely all versions containing the current `inflateAsync` implementation in `methods/inflater.js` **Patched version**: 0.6.1 ### Root Cause `methods/inflater.js:12-32` (`inflateAsync`) creates a `zlib.createInflateRaw(option)` stream and feeds it attacker-controlled compressed bytes via `tmp.end(inbuf)`, but ne |
| GitHub (opens in a new tab) | |
| GHSA-c6fg-446q-cg94 | Moderate | adm-zip: getDataAsync() bypasses the maxOutputLength size guard enforced by the synchronous getData() path### Summary adm-zip enforces a `maxOutputLength` guard against decompression bombs on its synchronous `getData()` path, but the equivalent asynchronous `getDataAsync()` path does not enforce it — it accumulates and returns the entire decompressed output regardless of the entry's declared size. An application that checks an entry's declared size before deciding to process it, then reads the entry via `getDataAsync()` (a completely ordinary, often-recommended choice for I/O in Node.js), gets none of the protection it believes it has. ### Details - `methods/inflater.js:3-10` passes `{maxOutput |
| GitHub (opens in a new tab) | |
| GHSA-j5f4-cc29-5x44 | High | adm-zip extraction preserves SUID/SGID bits from untrusted ZIPs -> local privilege escalation## Summary adm-zip applies the Unix permission bits stored in a zip entry directly to the extracted file via `fs.chmodSync()` when `keepOriginalPermission=true` is passed to `extractAllTo()`/`extractEntryTo()` — and it never filters the setuid/setgid/sticky bits out of those bits. A zip crafted by an attacker can therefore produce an extracted binary with mode `04755`. When extraction runs as root (the default posture in Docker builds, CI runners, and privileged install steps — the exact environments where this flag is used), the resulting root-owned setuid file is executed later by a lesser- |
| GitHub (opens in a new tab) | |
| GHSA-p634-w6r4-rjp2 | Moderate | adm-zip: Duplicate ZIP entry names: getEntry() and extractAllTo() resolve to different content### Summary A ZIP file can contain two entries with the identical name. adm-zip keeps both in its internal entry list, but its name-lookup table only retains the last one written. `getEntry(name)` and `extractAllTo()` walk these two different internal structures, so they can each resolve a duplicate name to a *different* entry. An application that validates a named entry's contents via `getEntry()` before trusting an archive, then extracts the whole archive, can end up approving one file's content while a different file's bytes are what actually land on disk under that name. ### Details - `z |
| GitHub (opens in a new tab) | |
| GHSA-rcw4-f5rp-g42v | High | adm-zip: Decompression-bomb protection (fix for CVE-2026-39244) can be bypassed by declaring uncompressed size as 0**Affected package:** adm-zip (npm) **Affected version:** 0.6.0 ## Summary The fix shipped for CVE-2026-39244 (`methods/inflater.js`) caps zlib's decompression output via `maxOutputLength: expectedLength`, where `expectedLength` is read directly from the ZIP entry's attacker-controlled "uncompressed size" header field (`CENLEN`/`LOCLEN`). This cap is only applied when `expectedLength > 0`: ```js const option = version >= 15 && expectedLength > 0 ? { maxOutputLength: expectedLength } : {}; return zlib.inflateRawSync(inbuf, option); ``` If an attacker sets the declared uncompressed-size fiel |
| GitHub (opens in a new tab) | |
| GHSA-7q85-xj36-vmfc | High | adm-zip: Uncontrolled memory allocation via the declared uncompressed size (DoS)### Summary adm-zip allocates an entry's output buffer from the declared uncompressed size (central-directory `size` field) before validating it against the actual data. A tiny crafted ZIP that declares a huge uncompressed size forces a multi-gigabyte allocation from a few bytes. ### Impact On adm-zip 0.5.17 (latest), Node 24, a 105-byte ZIP with one stored entry declaring size = 1,774,399,200 makes `new AdmZip(buf).getEntries()[0].getData()` commit ~1.8 GB of resident memory in ~4.4 s before throwing `Error: ADM-ZIP: CRC32 checksum failed`, roughly 16 million times the input size. Because th |
| GitHub (opens in a new tab) | |
| GHSA-vwc7-r8mq-g2x9 | Moderate | adm-zip extraction follows destination symlinks, allowing arbitrary file overwriteadm-zip 0.5.9 through 0.6.0 follows symbolic links at the extraction destination. Utils.sanitize in util/utils.js enforces containment by comparing only the string form of an archive entry name against the resolved extraction root, and Utils.writeFileTo opens the computed destination with fs.openSync(path, "w", 0o666), which resolves symbolic links and carries neither O_NOFOLLOW nor a pre-write fs.lstatSync check. When a path component at the destination already exists as a symbolic link pointing outside the extraction root, extractAllTo, extractAllToAsync and extractEntryTo write the entry co |
| GitHub (opens in a new tab) | |
| GHSA-xcpc-8h2w-3j85 | High | adm-zip: Crafted ZIP file triggers 4GB memory allocationadm-zip before 0.5.18 is vulnerable to denial of service via a crafted ZIP file with a manipulated uncompressed size header field. In zipEntry.js line 103, Buffer.alloc(_centralHeader.size) allocates memory based on the declared uncompressed size from the ZIP central directory header without validating it against the actual compressed data size or imposing any upper bound. The size value is read directly from the binary header at entryHeader.js line 266 with no bounds check. An attacker can craft a ~120-byte ZIP file that declares ~4GB uncompressed size, causing a memory allocation amplificati |
| GitHub (opens in a new tab) | |
| GHSA-3v6h-hqm4-2rg6 | Moderate | Arbitrary File Write in adm-zipVersions of `adm-zip` before 0.4.9 are vulnerable to arbitrary file write when used to extract a specifically crafted archive that contains path traversal filenames (`../../file.txt` for example). ## Recommendation Update to version 0.4.9 or later. |
| GitHub (opens in a new tab) |
- GHSA-8238-w5pm-2374Highadm-zip: Unhandled error event in async DEFLATE decompression crashes Node.js process (DoS)
< 0.6.1
## Summary Denial of Service in `adm-zip`'s async decompression API allows an unauthenticated attacker to crash the entire Node.js host process by supplying a single malformed ZIP file. ## Details **Affected package**: adm-zip **Affected versions**: at least 0.6.0 (current latest); likely all versions containing the current `inflateAsync` implementation in `methods/inflater.js` **Patched version**: 0.6.1 ### Root Cause `methods/inflater.js:12-32` (`inflateAsync`) creates a `zlib.createInflateRaw(option)` stream and feeds it attacker-controlled compressed bytes via `tmp.end(inbuf)`, but ne
CVE: CVE-2026-114102
- GHSA-c6fg-446q-cg94Moderateadm-zip: getDataAsync() bypasses the maxOutputLength size guard enforced by the synchronous getData() path
< 0.6.1
### Summary adm-zip enforces a `maxOutputLength` guard against decompression bombs on its synchronous `getData()` path, but the equivalent asynchronous `getDataAsync()` path does not enforce it — it accumulates and returns the entire decompressed output regardless of the entry's declared size. An application that checks an entry's declared size before deciding to process it, then reads the entry via `getDataAsync()` (a completely ordinary, often-recommended choice for I/O in Node.js), gets none of the protection it believes it has. ### Details - `methods/inflater.js:3-10` passes `{maxOutput
CVE: CVE-2026-114103
- GHSA-j5f4-cc29-5x44Highadm-zip extraction preserves SUID/SGID bits from untrusted ZIPs -> local privilege escalation
< 0.6.1
## Summary adm-zip applies the Unix permission bits stored in a zip entry directly to the extracted file via `fs.chmodSync()` when `keepOriginalPermission=true` is passed to `extractAllTo()`/`extractEntryTo()` — and it never filters the setuid/setgid/sticky bits out of those bits. A zip crafted by an attacker can therefore produce an extracted binary with mode `04755`. When extraction runs as root (the default posture in Docker builds, CI runners, and privileged install steps — the exact environments where this flag is used), the resulting root-owned setuid file is executed later by a lesser-
CVE: CVE-2026-102282
- GHSA-p634-w6r4-rjp2Moderateadm-zip: Duplicate ZIP entry names: getEntry() and extractAllTo() resolve to different content
< 0.6.1
### Summary A ZIP file can contain two entries with the identical name. adm-zip keeps both in its internal entry list, but its name-lookup table only retains the last one written. `getEntry(name)` and `extractAllTo()` walk these two different internal structures, so they can each resolve a duplicate name to a *different* entry. An application that validates a named entry's contents via `getEntry()` before trusting an archive, then extracts the whole archive, can end up approving one file's content while a different file's bytes are what actually land on disk under that name. ### Details - `z
CVE: CVE-2026-114104
- GHSA-rcw4-f5rp-g42vHighadm-zip: Decompression-bomb protection (fix for CVE-2026-39244) can be bypassed by declaring uncompressed size as 0
< 0.6.1
**Affected package:** adm-zip (npm) **Affected version:** 0.6.0 ## Summary The fix shipped for CVE-2026-39244 (`methods/inflater.js`) caps zlib's decompression output via `maxOutputLength: expectedLength`, where `expectedLength` is read directly from the ZIP entry's attacker-controlled "uncompressed size" header field (`CENLEN`/`LOCLEN`). This cap is only applied when `expectedLength > 0`: ```js const option = version >= 15 && expectedLength > 0 ? { maxOutputLength: expectedLength } : {}; return zlib.inflateRawSync(inbuf, option); ``` If an attacker sets the declared uncompressed-size fiel
CVE: CVE-2026-92000
- GHSA-7q85-xj36-vmfcHighadm-zip: Uncontrolled memory allocation via the declared uncompressed size (DoS)
< 0.6.1
### Summary adm-zip allocates an entry's output buffer from the declared uncompressed size (central-directory `size` field) before validating it against the actual data. A tiny crafted ZIP that declares a huge uncompressed size forces a multi-gigabyte allocation from a few bytes. ### Impact On adm-zip 0.5.17 (latest), Node 24, a 105-byte ZIP with one stored entry declaring size = 1,774,399,200 makes `new AdmZip(buf).getEntries()[0].getData()` commit ~1.8 GB of resident memory in ~4.4 s before throwing `Error: ADM-ZIP: CRC32 checksum failed`, roughly 16 million times the input size. Because th
CVE: CVE-2026-77301
- GHSA-vwc7-r8mq-g2x9Moderateadm-zip extraction follows destination symlinks, allowing arbitrary file overwrite
>= 0.5.9, <= 0.6.0
adm-zip 0.5.9 through 0.6.0 follows symbolic links at the extraction destination. Utils.sanitize in util/utils.js enforces containment by comparing only the string form of an archive entry name against the resolved extraction root, and Utils.writeFileTo opens the computed destination with fs.openSync(path, "w", 0o666), which resolves symbolic links and carries neither O_NOFOLLOW nor a pre-write fs.lstatSync check. When a path component at the destination already exists as a symbolic link pointing outside the extraction root, extractAllTo, extractAllToAsync and extractEntryTo write the entry co
CVE: CVE-2026-76845
- GHSA-xcpc-8h2w-3j85Highadm-zip: Crafted ZIP file triggers 4GB memory allocation
< 0.6.0
adm-zip before 0.5.18 is vulnerable to denial of service via a crafted ZIP file with a manipulated uncompressed size header field. In zipEntry.js line 103, Buffer.alloc(_centralHeader.size) allocates memory based on the declared uncompressed size from the ZIP central directory header without validating it against the actual compressed data size or imposing any upper bound. The size value is read directly from the binary header at entryHeader.js line 266 with no bounds check. An attacker can craft a ~120-byte ZIP file that declares ~4GB uncompressed size, causing a memory allocation amplificati
CVE: CVE-2026-39244
Versions of `adm-zip` before 0.4.9 are vulnerable to arbitrary file write when used to extract a specifically crafted archive that contains path traversal filenames (`../../file.txt` for example). ## Recommendation Update to version 0.4.9 or later.
CVE: CVE-2018-1002204