RUSTSEC-2026-0429 (CVE-2026-115909)
Vulnerability from osv_rustsec – Published: 2026-10-22 12:00 – Updated: 2026-11-02 09:50 – Source websiteZipArchive::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
| URL | Type | |
|---|---|---|
{
"affected": [
{
"database_specific": {
"categories": [
"denial-of-service"
],
"cvss": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"informational": null
},
"ecosystem_specific": {
"affected_functions": null,
"affects": {
"arch": [],
"functions": [],
"os": []
}
},
"package": {
"ecosystem": "crates.io",
"name": "zip",
"purl": "pkg:cargo/zip"
},
"ranges": [
{
"events": [
{
"introduced": "0.0.0-0"
},
{
"fixed": "9.0.0"
}
],
"type": "SEMVER"
}
],
"versions": []
}
],
"aliases": [
"CVE-2026-115909",
"GHSA-q7v9-x93c-xqv3"
],
"database_specific": {
"license": "CC0-1.0"
},
"details": "`ZipArchive::extract()` sizes the symlink-target buffer from the uncompressed\nsize declared in the central directory record, before reading a single byte of\nentry data:\n\n```rust\nlet mut target = Vec::with_capacity(file.size() as usize);\n```\n\nBoth inputs are attacker-controlled. `ZipFile::size()` returns\n`uncompressed_size` verbatim from the central directory, widened to a full `u64`\nby a ZIP64 extended-information extra field, and is never cross-checked against\nthe compressed size, the remaining archive length, or any platform-appropriate\nbound for a symlink target. `ZipFile::is_symlink()` is decided entirely by the\n`S_IFLNK` bit of the external-attributes field.\n\n`Vec::with_capacity()` is infallible: when the reservation is refused it calls\n`handle_alloc_error()` and aborts the process. This is not a Rust panic. It is\nnot caught by `catch_unwind()`, is unaffected by `panic = \"unwind\"`, and is not\ncontained by running the call on a worker thread.\n\nA 112-byte archive is sufficient. One `Stored` entry flagged `S_IFLNK` with a\nZIP64 field declaring `uncompressed_size = 2^62` and a zero-byte payload makes\n`extract()` fail with:\n\n```\nmemory allocation of 4611686018427387904 bytes failed\nAborted (core dumped) # exit 134\n```\n\nThe declared value only needs to exceed the host\u0027s address space, not its RAM:\n`Vec::with_capacity()` maps address space without touching pages, so resident\nmemory stays flat and the abort happens on the refused reservation itself. Under\na `ulimit -v` cap or a memory-constrained container the threshold drops far\nenough that a plain 32-bit `uncompressed_size` with no ZIP64 field suffices.\n\nApplications that extract archives from untrusted input are affected on Unix and\nWindows targets with default features and no special configuration: upload\nhandling, mail-attachment processing, package and artefact ingestion, backup\nrestore and container-image layer extraction. No confidentiality or integrity\nproperty is affected: there is no memory unsafety, no out-of-bounds access, no\ndisclosure and no data corruption.\n\nThe fix landed in [zip-rs/zip2#984](https://github.com/zip-rs/zip2/pull/984) and\nshipped in 9.0.0.\n\nFor further details see: https://github.com/zip-rs/zip2/security/advisories/GHSA-q7v9-x93c-xqv3",
"id": "RUSTSEC-2026-0429",
"modified": "2026-11-02T09:50:37Z",
"published": "2026-10-22T12:00:00Z",
"references": [
{
"type": "PACKAGE",
"url": "https://crates.io/crates/zip"
},
{
"type": "ADVISORY",
"url": "https://rustsec.org/advisories/RUSTSEC-2026-0429.html"
}
],
"related": [],
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "zip: `ZipArchive::extract` aborts the process on a symlink entry with a large declared size"
}
Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline
Sightings and recorded dates, grouped by day · UTC
Loading timeline…
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
Related by attack behaviour
Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.