RustSec logo

History ⋅ Edit ⋅ JSON (OSV)

RUSTSEC-2026-0429

zip: ZipArchive::extract aborts the process on a symlink entry with a large declared size

Reported
Issued
Package
zip (crates.io)
Type
Vulnerability
Categories
Keywords
#dos #symlink #unbounded-allocation #extract
Aliases
CVSS Score
7.5 HIGH
CVSS Details
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality Impact
None
Integrity Impact
None
Availability Impact
High
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Patched
  • >=9.0.0

Description

ZipArchive::extract() sizes the symlink-target buffer from the uncompressed size declared in the central directory record, before reading a single byte of entry data:

let mut target = Vec::with_capacity(file.size() as usize);

Both inputs are attacker-controlled. ZipFile::size() returns uncompressed_size verbatim from the central directory, widened to a full u64 by a ZIP64 extended-information extra field, and is never cross-checked against the compressed size, the remaining archive length, or any platform-appropriate bound for a symlink target. ZipFile::is_symlink() is decided entirely by the S_IFLNK bit of the external-attributes field.

Vec::with_capacity() is infallible: when the reservation is refused it calls handle_alloc_error() and aborts the process. This is not a Rust panic. It is not caught by catch_unwind(), is unaffected by panic = "unwind", and is not contained by running the call on a worker thread.

A 112-byte archive is sufficient. One Stored entry flagged S_IFLNK with a ZIP64 field declaring uncompressed_size = 2^62 and a zero-byte payload makes extract() fail with:

memory allocation of 4611686018427387904 bytes failed
Aborted (core dumped)          # exit 134

The declared value only needs to exceed the host's address space, not its RAM: Vec::with_capacity() maps address space without touching pages, so resident memory stays flat and the abort happens on the refused reservation itself. Under a ulimit -v cap or a memory-constrained container the threshold drops far enough that a plain 32-bit uncompressed_size with no ZIP64 field suffices.

Applications that extract archives from untrusted input are affected on Unix and Windows targets with default features and no special configuration: upload handling, mail-attachment processing, package and artefact ingestion, backup restore and container-image layer extraction. No confidentiality or integrity property is affected: there is no memory unsafety, no out-of-bounds access, no disclosure and no data corruption.

The fix landed in zip-rs/zip2#984 and shipped in 9.0.0.

For further details see: https://github.com/zip-rs/zip2/security/advisories/GHSA-q7v9-x93c-xqv3

Advisory available under CC0-1.0 license.