Repository navigation
chore(deps): move zip to 9 and rustls to 0.23.46 for RustSec advisories - #256
Conversation
`cargo audit` reports RUSTSEC-2026-0367, RUSTSEC-2026-0368 and RUSTSEC-2026-0369 against zip 2.4.2, which `zip = "2"` resolves to. All three are patched only in zip 9.0.0 and later. They concern `ZipArchive::extract()` and `ZipStreamReader::extract()`, which this crate never calls: the auto-upgrader's `extract_from_zip` walks entries with `by_index`, keeps only `enclosed_name()` paths and copies the one binary out itself. So the bump clears the audit rather than closing a path that was reachable here. zip 9 is taken with `default-features = false` and only the `deflate-flate2` feature. The upgrader only reads release archives, and every entry in the v0.23.0 Windows archive is Deflate; zip reads Stored entries without any feature. `deflate-flate2` decodes through the flate2 this crate already depends on, so flate2 keeps its miniz_oxide backend. zip 9's own `deflate` feature would also enable flate2's zlib-rs backend, which would switch every flate2 user in the build, including the tar.gz upgrade path, to zlib-rs. zip 2's default features built AES, bzip2, Deflate64, LZMA, XZ, zstd and Zopfli support that nothing here uses. Cargo.lock drops zip 2.4.2 and the thirteen crates only it needed (eleven for its default features, two for its fuzzing target), adds zip 9.0.5 and typed-path, and moves no other package. getrandom 0.3.4 loses its wasm-only js-sys and wasm-bindgen entries, because zip 2 was what enabled its `wasm_js` feature, and blake3's entry drops a version qualifier now that one constant_time_eq is left. zip 9 needs Rust 1.88, below this crate's `rust-version` of 1.95. No source change is needed: `ZipArchive::new`, `by_index`, `enclosed_name`, `ZipWriter` and `SimpleFileOptions` are unchanged for the calls made here.
dirvine
left a comment
There was a problem hiding this comment.
REQUEST_CHANGES — inherited Security Audit failure remains
Reviewed WithAutonomi/ant-node at exact head 328fa8dd5f5d293e90a2fe581da6cff0f56e8372 against base a6e3388e79d0907ef678bcb6ec0fcaa12822e148.
The ZIP change has no identified code blocker. The requested change is to clear the existing Rustls audit gate before approval of the current branch. It is not a defect introduced by this PR.
Required change: carry the Rustls fix, then rerun Security Audit
Cargo.lock:5146–5149 still locks rustls 0.23.45. Both the local audit and this head's failed Security Audit job report these four inherited advisory matches:
RUSTSEC-2026-0346RUSTSEC-2026-0347RUSTSEC-2026-0348RUSTSEC-2026-0349
Minimum fix: incorporate the narrow rustls 0.23.46 lockfile change from #255, or rebase onto it after it lands. Then rerun Security Audit on the updated head. No ZIP implementation change is requested, and no advisory ignore is needed.
I applied the exact #255 patch to a disposable copy of this PR's lockfile: cargo audit --json --no-fetch exited 0 with zero vulnerability matches. The five unmaintained and one unsound warnings were unchanged. #255 was still open at publication preflight.
Verified ZIP evidence
- Full diff covers
Cargo.tomlandCargo.lock: ZIP2.4.2 → 9.0.5,typed-path 0.12.3, reduced codec features and resulting graph changes. Both new registry archives match their lockfile checksums and are not yanked. Precise ZIP and typed-path updates from the base reproduce the submitted lockfile byte-for-byte; locked all-feature metadata succeeds. - Local audit control: base 7 vulnerability matches → PR head 4, with all three ZIP advisory matches (
RUSTSEC-2026-0367,RUSTSEC-2026-0368,RUSTSEC-2026-0369) removed and no new matches. The four remaining matches are the identical Rustls entries at base. deflate-flate2retains the existing miniz_oxide backend in the locked Linux musl, Windows MSVC and macOS graphs. The production extractor uses indexed reads and manual copying, not the advisory-affected bulkextract()methods.- Local Rust 1.95.0:
cargo +1.95.0 test --locked --lib --all-features upgrade::apply::tests -- --nocapture— 11 passed, zero failed. - Review-only harness using the frozen production extractor: 8 compatibility/rejection probes passed, including Stored/Deflate fixtures and a checksum-verified published Windows v0.23.0 ZIP. Extracted binary bytes match. This was run on macOS, not a native Windows or live auto-upgrade test.
- Exact-head CI: 19 passed; Security Audit failed as described above. Linux/macOS/Windows tests and builds, MSRV, storage and WebRTC checks passed.
Non-blocking follow-up: commit a Deflate ZIP regression test; the existing ZIP test helper emits Stored entries. Historical release archives beyond the sampled v0.23.0 archive were not exhaustively checked.
Panel and adjudication
4/6 role reviews, 2/3 named models — partial/provisional panel, not full consensus. GLM 5.3 (z-ai/glm-5.3) and Qwen 3.8 (qwen38-27b) completed both correctness and adversarial roles on the same complete evidence packet. Both DS4 (deepseek-v4-flash) roles hit the 120-second model-lock queue limit, including one same-model retry per role; neither produced an opinion.
All four responding role reviews recommend APPROVE for the ZIP change, subject to the Rustls merge-order gate. No new ZIP-code blocker was raised. My final REQUEST_CHANGES records that still-unmet audit prerequisite on the current head; it is not a claim that the panel rejected the ZIP implementation. Their conditional approval and this gate decision are recorded separately.
No merge, deployment or branch change performed.
`cargo audit` fails on RUSTSEC-2026-0346, RUSTSEC-2026-0347, RUSTSEC-2026-0348 and RUSTSEC-2026-0349 against `rustls` 0.23.45. All four are fixed in 0.23.46. They reached the RustSec database on 2026-10-14. Since then `main`'s lockfile fails `cargo audit`, and the Security Audit job fails whenever CI runs on a PR that still locks `rustls` 0.23.45. Only the `rustls` entry in `Cargo.lock` changes (version and checksum). 0.23.45 and 0.23.46 declare the same dependencies and `rust-version`, every existing requirement on `rustls` already allows the new patch, and the unique package lines of `cargo tree --locked --workspace --all-features --target all -e normal,build,dev --prefix none` differ only in the `rustls` version. `cargo update -p rustls` also moves `tempfile` from `getrandom` 0.4.3 to 0.3.4, a crate this fix has no reason to touch, so that line is kept as it was. Cargo 1.95, 1.98 and 1.99 accept the lockfile under `--locked` and find nothing to change with `--precise 0.23.46`.
The zip tests in `upgrade::apply` build their archives with Stored entries, so none of them decodes Deflate. Release zips use Deflate, and Deflate is the only compression method this crate now enables for zip. `create_zip_archive` now delegates to `create_zip_archive_with_method`, which takes the compression method. The new `test_extract_binary_from_deflated_zip` writes a compressible payload with Deflate, checks that the entry really is Deflate and smaller than its payload, then extracts it through `AutoApplyUpgrader::extract_binary` and compares the bytes.
dirvine
left a comment
There was a problem hiding this comment.
APPROVE — previous audit blocker resolved
Focused re-review of WithAutonomi/ant-node from prior-reviewed 328fa8dd5f5d293e90a2fe581da6cff0f56e8372 to current head 62ee59efce02b8f6ba519b6d8c3478b08e931da3, against unchanged base a6e3388e79d0907ef678bcb6ec0fcaa12822e148. This verifies the requested fixes, not a fresh review of unrelated code.
No remaining blocker from this review. This approval supersedes my previous REQUEST_CHANGES.
Previous blocker: resolved
Cargo.locknow pinsrustls 0.23.46. This clears the four previous matches:RUSTSEC-2026-0346,0347,0348and0349.- The incremental lockfile change is precisely Rustls's version and checksum. Its dependency list and all other package blocks are unchanged. This matches the narrow #255 patch. The downloaded registry archive matches the lockfile SHA-256; the release is not yanked and its MSRV is below project Rust 1.95.
- Fresh local
cargo audit --jsonexits 0 with zero vulnerability matches. The five unmaintained and one unsound warnings are unchanged from the prior reviewed head; they are not new findings from this delta. CI Security Audit also passes.
Deflate follow-up: addressed
The added test_extract_binary_from_deflated_zip verifies both the Deflate method and actual compression, then invokes the production AutoApplyUpgrader::extract_binary and checks extracted bytes. It cannot pass by silently writing a Stored ZIP. The existing helper retains Stored for the old tests. Production extraction and signature-verification code, and the manifest, are unchanged since my prior review.
Executed verification
On the exact raw head, locally on macOS with Rust 1.95.0:
cargo +1.95.0 test --locked --lib --all-features upgrade::apply::tests -- --nocapture: 12 passed; zero failed, including the new Deflate test.cargo +1.95.0 metadata --locked --all-features --format-version 1: exit 0.cargo +1.95.0 fmt --all -- --checkand base-to-headgit diff --check: exit 0.- Registry/checksum, package-block and unchanged-production-code assertions: passed.
All current CI checks pass, including Security Audit, MSRV, native builds/tests, storage and WebRTC devnet. I inspected the Linux, macOS and Windows test logs: the new Deflate test passes on all three. Those CI jobs execute synthetic merge 3caccec of this head into the base, not a raw-head checkout; local evidence above is raw-head execution.
Independent review coverage
6/6 focused role reviews, 3/3 named models: GLM 5.3 (z-ai/glm-5.3), Qwen 3.8 (qwen38-27b) and DS4 (deepseek-v4-flash) each completed correctness/evidence and adversarial reviews. All six recommend APPROVE; no material blocker dissent. DS4's adversarial first attempt expired in the 120-second model-lock queue; its one narrowed same-model retry completed. The retry retained the entire incremental diff and supporting evidence, removing only previously reviewed cumulative ZIP diff material.
Minor reviewer wording about fixture size and cumulative-versus-incremental manifest history was checked against source and is not adopted here. Model opinions are independent reasoning over the supplied evidence, not independent test executions.
Limits: no live auto-upgrade or new dedicated TLS interoperability smoke test was run in this follow-up. The previous published-Windows-ZIP compatibility probe is carried evidence; it was not re-executed. These are non-blocking limits, not claims of full production coverage.
No merge, deployment or PR branch change performed.
Linear issue
Closes V2-1633
Risk tier
Proposed rather than asserted. The only production code that uses
zipis the auto-upgrader's reader for the Windows release archive, so against the template's boundary question (it names the upgrade mechanism) this is a borderline call. That reader makes the same calls as before, and on the real v0.23.0 Windows release archive it extracts a byte-identical copy of theant-node.exepayload (Test evidence). The release workflow writes the published Windows zip with7z a, whose zip default is Deflate, and all six entries of the checked v0.23.0 archive are Deflate, so an archive built by the current release workflow is read as before. The second commit is #255'srustlspatch bump, unchanged, which #255 proposed as T1 on the same borderline reasoning. RustSec dependency bumps here (#209, #251) have been T1. If review wants T2, it needs a dev-testnet upgrade run and a linked ADR first.Compatibility
rustls0.23.46 and their compatibility evidence.extract_from_zipfunction. The upgrader loses support for entries compressed with bzip2, Deflate64, LZMA, XZ or zstd, which zip 2's default features enabled. AES support is no longer compiled, but encrypted entries were already rejected because the upgrader supplies no password. The release workflow writes none of these, and the checked v0.23.0 archive uses only Deflate.Semver impact
Test evidence
Run on this branch, three commits on top of
mainata6e3388e, with the RustSec database at999ec89d(1,338 advisories, its current head).cargo audit: onmain'sCargo.lockit reports seven vulnerabilities: RUSTSEC-2026-0367, -0368 and -0369 against zip 2.4.2, and RUSTSEC-2026-0346 to -0349 against rustls 0.23.45. After the zip commit only the four rustls ones remain. On this branch's head it reports none. The six warnings are the same throughout.cargo tree --locked --workspace --all-features --target all -e normal,build,dev --prefix none | sort -u,mainagainst the zip commit: zip 2.4.2 and the thirteen crates only it used (arbitrary, derive_arbitrary, bzip2, bzip2-sys, constant_time_eq 0.3.1, deflate64, lzma-rs, lzma-sys, xz2, zopfli, zstd, zstd-safe, zstd-sys) are gone, zip 9.0.5 and typed-path are added, and nix 0.31.3, already built for other crates, is now also a dependency of zip. Nothing else changes.Cargo.lockgoes from 714 to 702 packages. The rustls commit then changes only therustlsentry's version and checksum, byte for byte the same change as chore(deps): move rustls to 0.23.46 for four RustSec advisories #255.mainand on this branch (default,rust_backend,miniz_oxide) for x86_64 Linux musl, x86_64 Windows and aarch64 macOS, so Deflate decoding in both the zip and the tar.gz upgrade paths stays on miniz_oxide.cargo metadata --lockedaccepts the lockfile on cargo 1.95 (MSRV), 1.98 and 1.99,cargo update -p zip --precise 9.0.5 --dry-runandcargo update -p rustls --precise 0.23.46 --dry-runfind nothing to change, andcargo +1.95.0 check --locked --all-targets --all-featuresbuilds.cargo fmt --all -- --check,cargo clippy --locked --all-targets --all-features -- -D warnings(CI's flags, plus--locked),cargo clippy --locked -- -D warnings,cargo check --lib --no-default-features --lockedandcargo doc --locked --no-depswithRUSTDOCFLAGS=--deny=warnings: all clean.cargo test --locked --lib --features test-utils1189 passed, including the fourupgrade::applyzip tests. The newtest_extract_binary_from_deflated_zip(third commit) writes a Deflate entry, checks that it really is Deflate and smaller than its payload, and extracts it throughAutoApplyUpgrader::extract_binary. With zip's feature list emptied it no longer compiles, so it cannot pass without Deflate support. The other three build Stored archives.ant-node-cli-windows-x64.zip(SHA-256a30a722a…, matching the release'sSHA256SUMS.txt; all six entries Deflate) to the upgrader's ownAutoApplyUpgrader::extract_binary. It extracted the archive'sant-node.exepayload asant-nodeon the non-Windows test host, 22,229,136 bytes, with SHA-25631b6d670…, identical tounzip -p.scripts/third_party_notices/generate.pywith CI's five targets: passes, 523 crates, with licence texts found for zip 9.0.5 and typed-path. It now notes that its[native.bzip2-sys],[native.lzma-sys]and[native.zstd-sys]entries are unused: the binary no longer bundles libbzip2, liblzma or zstd C code.rustls0.23.46 evidence (e2e over real node transport, HTTPS upgrade check, production download smoke) is in chore(deps): move rustls to 0.23.46 for four RustSec advisories #255, on the samemain.New dependency
typed-path 0.12.3 (MIT OR Apache-2.0), a required dependency of zip 9. nix 0.31.3, already built for other crates, is now also a dependency of zip. The thirteen crates listed above leave the build.
rustlsonly moves a patch version.ADR
n/a, Tier 1.
Mitigation / rollback
Revert the commits. They touch only
Cargo.toml,Cargo.lockand one test module, and the release workflow writes none of the compression formats the narrower feature set leaves out.What this is
Three RustSec advisories, published 2026-10-09 and 2026-10-10, cover every zip release before 9.0.0:
extract()keeps SUID, SGID and sticky bits from the archive.extract()creates symlinks whose targets point outside the destination.extract()andZipStreamReader::extract()apply Unix permissions through such symlinks.ant-node never calls either
extract().extract_from_zipwalks the entries withby_index, skips any without anenclosed_name(), copies the one binary itself and sets its mode to 0o755. The archive's signature is checked before extraction. So this clears the audit; it does not close a path that was reachable here.Why Deflate only
The upgrader only reads release archives, which
Compress-Archiveand7zwrite with Deflate, and zip reads Stored entries without any feature. zip 9's default features would bring in AES, bzip2, Deflate64, LZMA, XZ, zstd, Zopfli and PPMd support, and new versions of several crypto and compression crates, none of which this crate uses.The feature is
deflate-flate2rather than zip'sdeflate.deflate-flate2decodes through the flate2 this crate already depends on, so flate2 keeps its miniz_oxide backend.deflatealso turns on flate2'szlib-rsfeature, and since Cargo unifies features, that would move every flate2 user here, the tar.gz upgrade path included, onto zlib-rs and add Zopfli. saorsa-labs/x0x tookdeflatein saorsa-labs/x0x#1444; this stays one step narrower so nothing outside zip changes.Why rustls is here too
mainstill locks rustls 0.23.45, so this PR's Security Audit job failed on RUSTSEC-2026-0346 to -0349 even after the zip move. The review asked for #255's narrow fix to be carried here so the audit can pass on this head. The second commit is #255's commit cherry-picked unchanged, and this head's Security Audit job passes. #255 is closed as superseded by this PR.Once a release ships with this, ant-client can drop zip 2.4.2: with WithAutonomi/ant-client#233, ant-node 0.23.0 is the only crate there still pulling it in.