Skip to content

Update dependency adm-zip to v0.6.1 [SECURITY] - #571

Merged
renovate[bot] merged 1 commit into
mainfrom
renovate/npm-adm-zip-vulnerability
Sep 21, 2026
Merged

renovate[bot] merged 1 commit into
mainfrom
renovate/npm-adm-zip-vulnerability

Conversation

@renovate

@renovate renovate Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
adm-zip 0.6.00.6.1 age confidence

adm-zip: Uncontrolled memory allocation via the declared uncompressed size (DoS)

CVE-2026-77301 / GHSA-7q85-xj36-vmfc

More information

Details

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 the buffer is committed before any validation, on a memory-constrained host (containers, serverless, small VMs) the allocation OOM-kills the process before the CRC check (uncatchable), and concurrent requests can exhaust memory even on larger hosts. Any service that reads entries from untrusted ZIPs is exposed to a remote denial of service.

Steps to reproduce

Attachments are not supported in the advisory form, so the 105-byte PoC (sha256 980d34356fbb248fe527b9d0ac3eabc5c99393a374014be6199523de16709386) is inlined as base64 in this self-contained reproducer:

const AdmZip = require('adm-zip');
// 105-byte crafted ZIP, base64-inlined
// sha256 980d34356fbb248fe527b9d0ac3eabc5c99393a374014be6199523de16709386
const b64 = "UEsDBBQAAAAAAAAAAAAAAAAABQAAAAUAAAABAAAAYWhlbGxvUEsBAhQAFAAAAAAAAAAAAAAAAAAFAAAA4C7DaQEAAAAAAAAAAAAAAAAAAAAAAGFQSwUGAAAAAAEAAQAvAAAAJAAAAAAA";
const buf = Buffer.from(b64, "base64");          // 105 bytes
const zip = new AdmZip(buf);
zip.getEntries()[0].getData();   // commits ~1.8 GB, then throws "ADM-ZIP: CRC32 checksum failed"

The single entry declares uncompressed size = 1,774,399,200 with a compressed size of 5. getData() allocates the full declared size before the CRC check runs, so the memory is committed regardless of the (tiny) actual payload.

Root cause

zipEntry.js does Buffer.alloc(<declared uncompressed size>) before checking the declared size against the compressed size / available bytes.

Suggested fix

Validate the declared uncompressed size against the compressed size and a configurable maximum before allocating (yauzl, for example, requires the caller to bound this); reject or stream when the declared size is implausible relative to the input. Happy to send a patch.

Severity

  • CVSS Score: 7.5 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

cthackers/adm-zip (adm-zip)

v0.6.1

Compare Source

Full Changelog: cthackers/adm-zip@v0.6.0...v0.6.1

  • Updated dev dependencies
  • Fixed uncaught crash in async decompression on malformed DEFLATE data
  • Fixed addLocalFolder following symlinks out of the archived folder
  • Stripped setuid/setgid/sticky bits from extracted file permissions
  • Enforced the decompression size cap on the async path and for size 0
  • Rejected archives with duplicate entry names
  • Blocked extraction from writing through symlinks inside the target
  • Routed malformed-header parse errors through the async callback
  • Rejected zip entries whose declared data extent runs past the buffer
  • Fixed addLocalFolderPromise hanging on empty folders and swallowing errors
  • Fixed addLocalFolderAsync2 mangling local paths on Windows

Configuration

📅 Schedule: (in timezone America/New_York)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate
renovate Bot merged commit bef666d into main Sep 21, 2026
4 checks passed
@renovate
renovate Bot deleted the renovate/npm-adm-zip-vulnerability branch September 21, 2026 00:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants