adm-zip

Ecosystem: npm

Downloads:

Vulnerabilities from the last (months)
  • 0CriticalAffects 0 versions
  • 5HighAffects 5 versions
  • 0MediumAffects 0 versions
  • 4ModerateAffects 4 versions
  • 0LowAffects 0 versions
Severity distribution (all time)
9vulnerabilities
  • 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.

Vulnerabilities affecting adm-zip
IDSeveritySummaryAffected versionsPublishedSource
GHSA-8238-w5pm-2374Highadm-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
  • < 0.6.1
GitHub (opens in a new tab)
GHSA-c6fg-446q-cg94Moderateadm-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
  • < 0.6.1
GitHub (opens in a new tab)
GHSA-j5f4-cc29-5x44Highadm-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-
  • < 0.6.1
GitHub (opens in a new tab)
GHSA-p634-w6r4-rjp2Moderateadm-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
  • < 0.6.1
GitHub (opens in a new tab)
GHSA-rcw4-f5rp-g42vHighadm-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
  • < 0.6.1
GitHub (opens in a new tab)
GHSA-7q85-xj36-vmfcHighadm-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
  • < 0.6.1
GitHub (opens in a new tab)
GHSA-vwc7-r8mq-g2x9Moderateadm-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
  • >= 0.5.9, <= 0.6.0
GitHub (opens in a new tab)
GHSA-xcpc-8h2w-3j85Highadm-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
  • < 0.6.0
GitHub (opens in a new tab)
GHSA-3v6h-hqm4-2rg6ModerateArbitrary 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.
  • < 0.4.11
GitHub (opens in a new tab)
  • GHSA-8238-w5pm-2374High
    adm-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-cg94Moderate
    adm-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-5x44High
    adm-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-rjp2Moderate
    adm-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-g42vHigh
    adm-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-vmfcHigh
    adm-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-g2x9Moderate
    adm-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-3j85High
    adm-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

  • GHSA-3v6h-hqm4-2rg6Moderate
    Arbitrary File Write in adm-zip
    • < 0.4.11

    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

Showing 1-9 of 9 vulnerabilities