CVE-2026-115908
zip: Arbitrary file write outside the extraction directory, because ZipArchive::extract validates symlink targets lexically. (The defense against CVE-2025-29787 was broken in v7.2.0)
zip is a zip library for Rust that supports reading and writing simple ZIP files. From 7.2.0 until 9.0.0, ZipArchive::extract and ZipArchive::extract_unwrapped_root_dir use safe_prepare_path in src/read/zipfile.rs and simplified_components in src/path.rs to validate symbolic link targets with a lexical prefix comparison rather than resolving each intermediate link. An attacker who knows or can guess the absolute extraction destination can create a chain whose apparent target remains under the destination while an intermediate symlink resolves outside it, allowing attacker-controlled files to be created or overwritten with the extracting process's privileges. On Windows, discarded drive and UNC prefixes can permit a single-link escape when the process has SeCreateSymbolicLinkPrivilege, such as through administrator rights or Developer Mode. This regression is distinct from CVE-2025-29787. This issue is fixed in version 9.0.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- High
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
7.4
zip: Arbitrary file write outside the extraction directory, because ZipArchive::extract validates symlink targets lexically. (The defense against CVE-2025-29787 was broken in v7.2.0)
zip is a zip library for Rust that supports reading and writing simple ZIP files. From 7.2.0 until 9.0.0, ZipArchive::extract and ZipArchive::extract_unwrapped_root_dir use safe_prepare_path in src/read/zipfile.rs and simplified_components in src/path.rs to validate symbolic link targets with a lexical prefix comparison rather than resolving each intermediate link. An attacker who knows or can guess the absolute extraction destination can create a chain whose apparent target remains under the destination while an intermediate symlink resolves outside it, allowing attacker-controlled files to be created or overwritten with the extracting process's privileges. On Windows, discarded drive and UNC prefixes can permit a single-link escape when the process has SeCreateSymbolicLinkPrivilege, such as through administrator rights or Developer Mode. This regression is distinct from CVE-2025-29787. This issue is fixed in version 9.0.0.
- Record
CVE-2026-115908- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:H - Weakness
- CWE-22, CWE-59, CWE-61
- Updated
- 2026-11-02
EUVDEUVD-2026-109985
7.4
zip is a zip library for Rust that supports reading and writing simple ZIP files. From 7.2.0 until 9.0.0, ZipArchive::extract and ZipArchive::extract_unwrapped_root_dir use safe_prepare_path in src/read/zipfile.rs and simplified_components in src/path.rs to validate symbolic link targets with a lexical prefix comparison rather than resolving each intermediate link. An attacker who knows or can guess the absolute extraction destination can create a chain whose apparent target remains under the destination while an intermediate symlink resolves outside it, allowing attacker-controlled files to be created or overwritten with the extracting process's privileges. On Windows, discarded drive and UNC prefixes can permit a single-link escape when the process has SeCreateSymbolicLinkPrivilege, such as through administrator rights or Developer Mode. This regression is distinct from CVE-2025-29787. This issue is fixed in version 9.0.0.
- Record
EUVD-2026-109985- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-hjqx-j4rw-g7xv
7.4
zip: Arbitrary file write outside the extraction directory, because ZipArchive::extract validates symlink targets lexically.
Summary
- Verified version: zip
9.0.0-pre3 - Affected versions:
7.2.0and later - Precondition: The attacker knows (or can guess) the absolute path of the extraction destination
The validation applied to symlinks is purely lexical.
As a result, an attacker can write arbitrary files outside the extraction directory through a symlink.
Exploitation requires the attacker to know (or guess) the absolute path of the destination, but this is realistic in practice: CI workspaces, /opt/app, a fixed Downloads path, and so on.
Impact extends further on Windows (verified on real hardware for both the separate-drive and UNC-share cases):
Becausesimplified_componentsdiscards thePrefixcomponent, paths likeD:\<same tail as dest>or a UNC path\\attacker\share\<same tail>pass thestarts_withcheck.
As a result,outpath.pushgets replaced onto a different drive/remote share, so a single symlink is enough — no intermediate symlink chain is required.
That said, creating a symlink on Windows requiresSeCreateSymbolicLinkPrivilege(administrator rights or Developer Mode enabled). Real-hardware verification (Windows 10 VM (19045.2604),tests/poc_win.rs):
With the extraction target set to a temporary directory underC:, both of the following paths returnedOk(())fromextract()and successfully wrote outside the extraction target.
In both casesextract()returned no error (Ok(())), and it was confirmed that the contents ofpwned.txtmatched the attacker-specified value.
Relationship to CVE-2025-29787
This is not a duplicate of the existing CVE-2025-29787 (2025-03); rather, the protection introduced for that CVE was subsequently lost.
Timeline (git history, UTC)
| commit | Date | Description |
| ---------- | ---------- | ---------------------------------------------------------------------------------------------------------------- |
| d4539d6b | 2025-02-28 | Initial fix for CVE-2025-29787. Canonicalizes output paths and symlink targets and verifies they descend from the destination |
| 0199ac2c | 2025-03-15 | Before the v2.3.0 release, the above is replaced with a lexical check based on simplified_components |
| v2.3.0 | 2025-03-16 | Released as the CVE fix. What actually shipped is the lexical check |
| d5cf4b55 | 2026-01-18 | Changes how simplified_components handles absolute paths, from rejecting them to silently stripping them (released in v7.2.0) |
Why v2.3.0 was not affected, and how the protection was lost
The safe_prepare_path in v2.3.0 performs essentially the same lexical check as the current code. However, simplified_components at that time rejected any path containing an absolute component, so an absolute symlink target was never accepted in the first place and this attack path did not work.
// v2.3.0: reject absolute paths
Component::Prefix(_) | Component::RootDir => return None,
// Current: ignore the fact that the path is absolute
Utf8WindowsComponent::Prefix(_) | Utf8WindowsComponent::RootDir => (),
d5cf4b55 was intended to make archives containing absolute path names extractable, but as a side effect absolute symlink targets now pass the lexical check, which silently removed the protection against CVE-2025-29787.
Verification
The following three cases were compared using the same build (9.0.0-pre3):
| Payload / condition | Result | | -------------------------------------------------------------------------- |…
- Record
GHSA-hjqx-j4rw-g7xv- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:H - Weakness
- CWE-22, CWE-59, CWE-61
- Updated
- 2026-11-02
NVD
7.4
zip is a zip library for Rust that supports reading and writing simple ZIP files. From 7.2.0 until 9.0.0, ZipArchive::extract and ZipArchive::extract_unwrapped_root_dir use safe_prepare_path in src/read/zipfile.rs and simplified_components in src/path.rs to validate symbolic link targets with a lexical prefix comparison rather than resolving each intermediate link. An attacker who knows or can guess the absolute extraction destination can create a chain whose apparent target remains under the destination while an intermediate symlink resolves outside it, allowing attacker-controlled files to be created or overwritten with the extracting process's privileges. On Windows, discarded drive and UNC prefixes can permit a single-link escape when the process has SeCreateSymbolicLinkPrivilege, such as through administrator rights or Developer Mode. This regression is distinct from CVE-2025-29787. This issue is fixed in version 9.0.0.
- Record
CVE-2026-115908- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:H - Weakness
- CWE-22, CWE-59, CWE-61
- Updated
- 2026-11-02
OSV
7.4
zip: Arbitrary file write outside the extraction directory, because ZipArchive::extract validates symlink targets lexically. (The defense against CVE-2025-29787 was broken in v7.2.0)
zip is a zip library for Rust that supports reading and writing simple ZIP files. From 7.2.0 until 9.0.0, ZipArchive::extract and ZipArchive::extract_unwrapped_root_dir use safe_prepare_path in src/read/zipfile.rs and simplified_components in src/path.rs to validate symbolic link targets with a lexical prefix comparison rather than resolving each intermediate link. An attacker who knows or can guess the absolute extraction destination can create a chain whose apparent target remains under the destination while an intermediate symlink resolves outside it, allowing attacker-controlled files to be created or overwritten with the extracting process's privileges. On Windows, discarded drive and UNC prefixes can permit a single-link escape when the process has SeCreateSymbolicLinkPrivilege, such as through administrator rights or Developer Mode. This regression is distinct from CVE-2025-29787. This issue is fixed in version 9.0.0.
- Record
CVE-2026-115908- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:H - Weakness
- CWE-22, CWE-59, CWE-61
- Updated
- 2026-11-07
OSVGHSA-hjqx-j4rw-g7xv
7.4
zip: Arbitrary file write outside the extraction directory, because ZipArchive::extract validates symlink targets lexically.
Summary
- Verified version: zip
9.0.0-pre3 - Affected versions:
7.2.0and later - Precondition: The attacker knows (or can guess) the absolute path of the extraction destination
The validation applied to symlinks is purely lexical.
As a result, an attacker can write arbitrary files outside the extraction directory through a symlink.
Exploitation requires the attacker to know (or guess) the absolute path of the destination, but this is realistic in practice: CI workspaces, /opt/app, a fixed Downloads path, and so on.
Impact extends further on Windows (verified on real hardware for both the separate-drive and UNC-share cases):
Becausesimplified_componentsdiscards thePrefixcomponent, paths likeD:\<same tail as dest>or a UNC path\\attacker\share\<same tail>pass thestarts_withcheck.
As a result,outpath.pushgets replaced onto a different drive/remote share, so a single symlink is enough — no intermediate symlink chain is required.
That said, creating a symlink on Windows requiresSeCreateSymbolicLinkPrivilege(administrator rights or Developer Mode enabled). Real-hardware verification (Windows 10 VM (19045.2604),tests/poc_win.rs):
With the extraction target set to a temporary directory underC:, both of the following paths returnedOk(())fromextract()and successfully wrote outside the extraction target.
In both casesextract()returned no error (Ok(())), and it was confirmed that the contents ofpwned.txtmatched the attacker-specified value.
Relationship to CVE-2025-29787
This is not a duplicate of the existing CVE-2025-29787 (2025-03); rather, the protection introduced for that CVE was subsequently lost.
Timeline (git history, UTC)
| commit | Date | Description |
| ---------- | ---------- | ---------------------------------------------------------------------------------------------------------------- |
| d4539d6b | 2025-02-28 | Initial fix for CVE-2025-29787. Canonicalizes output paths and symlink targets and verifies they descend from the destination |
| 0199ac2c | 2025-03-15 | Before the v2.3.0 release, the above is replaced with a lexical check based on simplified_components |
| v2.3.0 | 2025-03-16 | Released as the CVE fix. What actually shipped is the lexical check |
| d5cf4b55 | 2026-01-18 | Changes how simplified_components handles absolute paths, from rejecting them to silently stripping them (released in v7.2.0) |
Why v2.3.0 was not affected, and how the protection was lost
The safe_prepare_path in v2.3.0 performs essentially the same lexical check as the current code. However, simplified_components at that time rejected any path containing an absolute component, so an absolute symlink target was never accepted in the first place and this attack path did not work.
// v2.3.0: reject absolute paths
Component::Prefix(_) | Component::RootDir => return None,
// Current: ignore the fact that the path is absolute
Utf8WindowsComponent::Prefix(_) | Utf8WindowsComponent::RootDir => (),
d5cf4b55 was intended to make archives containing absolute path names extractable, but as a side effect absolute symlink targets now pass the lexical check, which silently removed the protection against CVE-2025-29787.
Verification
The following three cases were compared using the same build (9.0.0-pre3):
| Payload / condition | Result | | -------------------------------------------------------------------------- |…
- Record
GHSA-hjqx-j4rw-g7xv- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:H - Weakness
- CWE-22, CWE-59, CWE-61
- Updated
- 2026-11-02
Show 6 moreShow less
OSVUBUNTU-CVE-2026-115908
7.4
zip is a zip library for Rust that supports reading and writing simple ZIP files. From 7.2.0 until 9.0.0, ZipArchive::extract and ZipArchive::extract_unwrapped_root_dir use safe_prepare_path in src/read/zipfile.rs and simplified_components in src/path.rs to validate symbolic link targets with a lexical prefix comparison rather than resolving each intermediate link. An attacker who knows or can guess the absolute extraction destination can create a chain whose apparent target remains under the destination while an intermediate symlink resolves outside it, allowing attacker-controlled files to be created or overwritten with the extracting process's privileges. On Windows, discarded drive and UNC prefixes can permit a single-link escape when the process has SeCreateSymbolicLinkPrivilege, such as through administrator rights or Developer Mode. This regression is distinct from CVE-2025-29787. This issue is fixed in version 9.0.0.
- Record
UBUNTU-CVE-2026-115908- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/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
OSVopenSUSE-SU-2026:12333-1 No score
keylime-ima-policy-0.2.10+12-1.1 on GA media
These are all security issues fixed in the keylime-ima-policy-0.2.10+12-1.1 package on the GA media of openSUSE Tumbleweed.
- Record
openSUSE-SU-2026:12333-1- Updated
- 2026-11-02
OSVopenSUSE-SU-2026:12454-1 No score
gleam-1.19.2-1.1 on GA media
These are all security issues fixed in the gleam-1.19.2-1.1 package on the GA media of openSUSE Tumbleweed.
- Record
openSUSE-SU-2026:12454-1- Updated
- 2026-11-07
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
| Package | Affected | Fixed |
|---|---|---|
zipcrates.io |
7.2.0 up to 9.0.0 | 9.0.0 |
rust-keylimeSUSE: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-keylimeSUSE: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-zipUbuntu:26.10 |
All versions, plus listed versions 5.1.1-35.1.1+dfsg-1 |
None known |
rust-zipUbuntu:26.04:LTS |
All versions, plus listed versions 2.5.0-15.1.1-25.1.1-3 |
None known |
python-uvopenSUSE:Tumbleweed From an advisory covering 3 CVEs |
before 0.13.6-1.1 | 0.13.6-1.1 |
rust-keylimeopenSUSE:Tumbleweed From an advisory covering 2 CVEs |
before 0.2.10+12-1.1 | 0.2.10+12-1.1 |
gleamopenSUSE:Tumbleweed From an advisory covering 3 CVEs |
before 1.19.2-1.1 | 1.19.2-1.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, aliases, references | OSV | |
| affected | ||
| affected, facts | OSV | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-115908 is a high vulnerability (CVSS 7.4) 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.43%, the 37th percentile. Fixed in zip 9.0.0.
References
github.com/zip-rs/zip2/security/advisories/GHSA-hjqx-j4rw-g7xv
github.com/zip-rs/zip2/commit/09c030eab56e8db8fb3c1c33f554407b30bad8fa
github.com/zip-rs/zip2/releases/tag/v9.0.0
nvd.nist.gov/vuln/detail/CVE-2026-115908
github.com/advisories/GHSA-hjqx-j4rw-g7xv
github.com/CVEProject/cvelistV5/tree/main/cves/2026/115xxx/CVE-2026-115908.json
Show 15 moreShow less
github.com/zip-rs/zip2
suse.com/support/update/announcement/2026/suse-su-20264930-1
bugzilla.suse.com/1287921
suse.com/security/cve/CVE-2026-115905
suse.com/security/cve/CVE-2026-115906
suse.com/security/cve/CVE-2026-115907
suse.com/security/cve/CVE-2026-115908
suse.com/security/cve/CVE-2026-115909
suse.com/support/update/announcement/2026/suse-su-20264931-1
ubuntu.com/security/CVE-2026-115908
cve.org/CVERecord?id=CVE-2026-115908
github.com/zip-rs/zip2/security/advisories/ghsa-hjqx-j4rw-g7xv
github.com/cveproject/cvelistv5/tree/main/cves/2026/115xxx/cve-2026-115908.json
nvd.nist.gov/vuln/detail/cve-2026-115908
suse.com/security/cve/CVE-2026-103061
Left out here: the rest of 2 source descriptions. The JSON record has them.