On this page (7 sections)
The Rust zip library (the zip crate, maintained in the zip-rs/zip2 repository) has a critical flaw tracked as CVE-2026-115905. In versions up to and including 9.0.4, two of its readers can disagree about which file an archive contains. A crafted ZIP can look harmless to a component that inspects it, then cause a streaming extractor to write a different file to a different path. The GitHub advisory calls this "Zip Cloaking".
If you run a service written in Rust that accepts ZIP uploads, or any pipeline where one component checks an archive and another extracts it, you should check your dependency version now. So far this story rests on the project's own advisory; no independent coverage or exploitation reports were found.
What happened
A ZIP file describes each entry in two places. The Local File Header (LFH) sits right before each file's data. The Central Directory File Header (CDFH) is an index at the end of the archive. A well-formed archive keeps the two consistent. The advisory explains that the zip crate's two readers trust different copies.
- ZipArchive (random access) treats the central directory as authoritative and ignores the filename in the local header.
- ZipStreamReader (streaming) reads entries in order and writes them to disk using the filename from the local header, without checking it against the central directory.
This kind of weakness is called a parser differential: the same bytes mean different things to different programs. Security tools that only see the "clean" view can approve something that the extractor treats very differently.
Technical details
According to the advisory, the problem is in src/read/stream.rs, where ZipStreamReader::visit and ZipStreamReader::extract write each entry using the unverified local-header name. The CVE record describes the outcome: an archive can appear benign to a component that inspects the central directory, yet make a streaming extractor write an attacker-selected path and content, potentially overwriting files used by a downstream service.
The advisory also notes that the crate exposes a shallow_copy_file API in src/write.rs, which can create this kind of header desynchronization by adding a central directory entry with an alias name without updating the original local header. That matters mainly for anyone generating archives with the crate.
The threat scenario
The advisory's scenario is a two-stage pipeline. An upload endpoint is protected by a gateway (WAF, antivirus or content disarm tooling) that reads the central directory and sees only a harmless document. A backend worker then extracts the same archive with ZipStreamReader, which follows the local header and writes a different file, for example replacing a service script. The advisory argues this could lead to file overwrite, denial of service and code execution. These are the reporter's severity claims; the research gives no evidence of real attacks.
Who is affected
You are exposed if all of the following apply:
- Your code depends on the zip crate at version 9.0.4 or earlier, directly or through another crate.
- It extracts untrusted archives using ZipStreamReader.
- The extraction runs with write access to files that matter, such as scripts, configuration or service data.
- Ideally for the attacker, a different tool inspects the archive first and its approval is trusted.
If you only use ZipArchive to read archives, or never handle archives from outside your trust boundary, the described attack path is much narrower. The research does not say whether other uses of the crate are affected, so confirm by upgrading rather than by reasoning alone.
How to check your exposure
Run these read-only commands from the root of your Rust project. The first lists which version of the zip crate your lockfile resolved, including copies pulled in by other dependencies. Look for any version at or below 9.0.4.
cargo tree -i zipThe second finds the pinned version in the lockfile. Check the version line that follows the zip package entry.
grep -n -A1 'name = "zip"' Cargo.lockThen search your own source for streaming extraction, which is the code path the advisory describes.
grep -rn "ZipStreamReader" --include=*.rs .What to do now
The fix is in zip 9.0.5. Update the dependency, rebuild and redeploy.
cargo update -p zip0 of 7 done
Detection and monitoring
The research gives no indicators of compromise, so detection is about behavior. Watch for unexpected modifications to scripts, cron jobs and service files on hosts that process uploads, and for extraction workers writing outside their intended directory. File integrity monitoring and tight filesystem permissions on those hosts help here.
If you run a public site with upload features, an outside view is useful too. A Webforta Scan can review a site you verify for exposed issues, and Webforta Monitor can alert you to certificate, DNS and header changes. Neither inspects your Rust dependencies, so use your own dependency auditing for that. For background on how upload filtering fits into a layered defense, see What is a WAF?.
If you suspect an archive was used against you, follow the steps in Website hacked: what to do and restore any overwritten files from known-good sources.
Timeline
- Oct 17, 2026: advisory GHSA-m665-v7pm-7grj published in zip-rs/zip2 (per the GitHub advisory page).
- Oct 26, 2026: CVE-2026-115905 published (per the CVE record).
- Oct 28, 2026: advisory last updated.
- Fixed version: zip 9.0.5.
The research does not state the exact release date of 9.0.5 or who reported the issue.
Sources
This article is based on the public sources below. Details can change as vendors and researchers publish more; check the original advisories before acting on version numbers.
