# cargo-audit configuration for AeroFTP # # Each ignore below carries a written justification. Reviewers (OpenSSF, # OSSSign, supply-chain auditors) should read these inline and either accept # them or push back with a specific objection. We do NOT ignore advisories # without a tracked rationale. # # Companion documents: # - docs/THREAT-MODEL.md (the matching threat model) # - docs/dev/roadmap/APPENDIX-RUSSH_RSA-Decommission-Plan.md (russh path) # - docs/dev/roadmap/APPENDIX-SIGSTORE_*.md (sigstore path, planned) # - docs/security-evidence/AEROFTP-CLI-AUDIT-2026-05-06.md (origin audit) # # Reviewed: 2026-06-03 (added two russh advisories, deferred to 0.61 bump #251) # Reviewed: 2026-06-03 (dual-audit CODEX-AV-007: bumped yanked aes 0.9.0 -> 0.9.1 # in Cargo.lock via zip/russh; corrected Path B version refs to the # resolved russh 0.60.3 / rsa 0.10.0-rc.16) # Reviewed: 2026-06-08 (added RUSTSEC-2024-0384 `instant`, pulled transitively by # the new AeroVault v4 ECC dep reed-solomon-erasure; and RUSTSEC-2026-0173 # `proc-macro-error2`, freshly published on the existing sigstore build path) # Reviewed: 2026-06-15 (v4.0.5: bumped russh 0.60.3 -> 0.61.2 once the upstream # 0.61.0/0.61.1 RC-crypto packaging conflict cleared at 0.61.2; REMOVED # the two deferred russh ignores GHSA-wwx6-x28x-8259 + GHSA-hpv4-5h6f-wqr3, # now fixed. RUSTSEC-2023-0071 Path B kept: russh 0.61.2 still reaches `rsa` # via its forked ssh-key for SSH key parsing, sign-only (no decrypt oracle).) # Reviewed: 2026-06-26 (iroh 0.92 -> 1.0 migration: REMOVED three now-moot ignores # RUSTSEC-2026-0118 + RUSTSEC-2026-0119 (hickory-proto, fixed in 0.26.1) and # RUSTSEC-2026-0002 (lru, patched 0.18.0 / unaffected 0.7.8). Only the two # UNMAINTAINED iroh-graph advisories remain (atomic-polyfill, paste).) # Reviewed: 2026-06-26 (sigstore 0.13 -> 0.14 bump: REMOVED the two tough ignores # GHSA-4v58-8p28-2rq3 + GHSA-8m7c-8m39-rv4x (sigstore 0.14 pulls tough 0.22, # both fixed) and RUSTSEC-2026-0173 proc-macro-error2 (no longer in the graph: # oci-spec 0.9 drops the getset edge). 0.14 also adds bundle-format v0.3 parsing, # so verify_sigstore_bundle finally returns SigstoreVerified on real releases; # only the `verify` feature is enabled, dropping the broken `sign` path. RSA # Path A kept: openidconnect 4.0.1 still reaches rsa 0.9.10, dormant/non-blocking.) # Reviewed: 2026-06-29 (added RUSTSEC-2026-0190, n0-error downcast_mut unsoundness freshly # published to the advisory DB, transitive via iroh 1.0; unsoundness not a vuln, # pinned by iroh with no in-tree upgrade, AeroFTP never calls downcast_mut.) # Reviewed: 2026-07-02 (RUSTSEC-2026-0194 + RUSTSEC-2026-0195 quick-xml DoS freshly # published: BUMPED the direct dep quick-xml 0.40 -> 0.41 to patch the real # runtime path (WebDAV/S3/Azure/STS response parsing, the only surface fed # untrusted remote XML). Ignored the two IDs for the two remaining # Tauri-transitive instances (winrt-notification 0.37.5, plist 0.39.4), which # parse app-owned XML only, awaiting a Tauri stack bump.) [advisories] ignore = [ # ---------------------------------------------------------------- # RUSTSEC-2023-0071 - Marvin Attack on RSA decryption # ---------------------------------------------------------------- # Marvin is a timing side-channel observable when an attacker can request # repeated RSA *decrypt* operations and measure response time. AeroFTP's # two transitive paths to the `rsa` crate never expose a decrypt oracle: # # Path A (rsa 0.9.10): # rsa <- openidconnect 4.0.1 <- sigstore 0.14.0 <- aeroftp # Used by `verify_sigstore_bundle` in src-tauri/src/lib.rs to verify # GitHub Actions Sigstore bundles attached to release artifacts. # Fulcio signs short-lived certificates with ECDSA P-256, not RSA. # The `rsa` crate is dormant in this call graph. # Verification path is also explicitly NON-BLOCKING (see lib.rs ~2300): # any verification error degrades to `VerificationMode::Unavailable` # instead of refusing the update; SHA-256 of the artifact is the # primary integrity check. # # Path B (rsa 0.10.0-rc.16): # rsa <- internal-russh-forked-ssh-key 0.6.18 <- russh 0.60.3 <- aeroftp # Used to parse user SSH private keys (id_rsa, etc.) and sign SSH auth # challenges in providers/sftp.rs and aerorsync/russh_session_transport.rs. # AeroFTP only ever SIGNS with the user's RSA private key (RFC 4252 + # RFC 8332 client publickey auth flow); the server VERIFIES. We never # decrypt RSA ciphertext. The Marvin precondition (attacker-observable # RSA decrypt) is not reachable through our SSH client surface. # # Both paths await upstream resolution (see APPENDIX-RUSSH and the # planned APPENDIX-SIGSTORE for the deferred decommission playbooks). # russh `main` has introduced a `rsa` feature flag that will allow # opt-out, but it has not landed in a published release as of 2026-05-06. # `rsa 0.10` itself is still RC since 2023. "RUSTSEC-2023-0071", # ---------------------------------------------------------------- # GTK3 unmaintained (transitive via Tauri / wry) # ---------------------------------------------------------------- # `atk`, `atk-sys`, `gdk`, `gdk-sys`, `gdkx11`, `gdkx11-sys`, `gtk`, # `gtk-sys`, `gdk-pixbuf`, `gdk-pixbuf-sys`, `gio`, `gio-sys`, `glib`, # `glib-sys`, `gobject-sys`, `pango`, `pango-sys`, `cairo-rs`, `cairo-sys-rs` # all flagged as unmaintained because gtk-rs upstream paused GTK3 # bindings in favour of GTK4. Pulled in by `wry 0.54` <- `tauri-runtime-wry` # <- `tauri 2.x` for the WebKitGTK Linux WebView. AeroFTP cannot # unilaterally migrate to GTK4 — it is a Tauri-stack-wide decision. # Tracked upstream by Tauri team; expected to land with the next # minor (Tauri 2.11+ already in flight, see PR #168). "RUSTSEC-2024-0412", # gdk "RUSTSEC-2024-0413", # atk "RUSTSEC-2024-0416", # atk-sys "RUSTSEC-2024-0418", # gdk-sys "RUSTSEC-2024-0420", # gdkx11 "RUSTSEC-2024-0421", # gdkx11-sys "RUSTSEC-2024-0414", # gtk "RUSTSEC-2024-0415", # gtk-sys "RUSTSEC-2024-0419", # gdk-pixbuf "RUSTSEC-2024-0411", # gdkwayland-sys (via tao) "RUSTSEC-2024-0417", # gdkx11 (separate ID) # ---------------------------------------------------------------- # proc-macro-error unmaintained (transitive via Tauri / tray-icon) # ---------------------------------------------------------------- # `proc-macro-error 1.0.4` <- `glib-macros 0.18.5` <- `glib 0.18.5` <- # `gtk 0.18.2` <- `tray-icon 0.21.3` <- `tauri 2.10.3`. Same gtk-rs # paused-bindings situation. Will clear when Tauri ships GTK4 wry. "RUSTSEC-2024-0370", # proc-macro-error # ---------------------------------------------------------------- # unic-* unmaintained (build-dep only via tauri-utils / urlpattern) # ---------------------------------------------------------------- # `unic-char-property`, `unic-char-range`, `unic-common`, `unic-ucd-ident`, # `unic-ucd-version` are all pulled by `urlpattern 0.3.0` <- `tauri-utils` # <- `tauri-build` (build-dependency) <- aeroftp. Used at build-time for # URL pattern matching in Tauri's CSP / asset scope code generation. # Not in runtime binary. Tauri tracks the urlpattern bump upstream. "RUSTSEC-2025-0075", # unic-char-range "RUSTSEC-2025-0080", # unic-common "RUSTSEC-2025-0081", # unic-char-property "RUSTSEC-2025-0098", # unic-ucd-version "RUSTSEC-2025-0100", # unic-ucd-ident # ---------------------------------------------------------------- # glib 0.18 unsound (transitive via Tauri / wry) # ---------------------------------------------------------------- # `glib 0.18.5` carries a soundness advisory for unsafe code in # `gobject-sys::g_object_get`. Same supply-chain situation as the # GTK3 unmaintained set above (Tauri 2.x stack). Cannot be dropped # without dropping Tauri Linux support entirely. Will be cleared # automatically when Tauri ships GTK4-based wry. "RUSTSEC-2024-0429", # glib # ---------------------------------------------------------------- # rand 0.7.3 unsound (build-dep only via Tauri stack) # ---------------------------------------------------------------- # `rand 0.7.3` is a *build-dependency* via: # rand 0.7.3 <- phf_generator 0.8.0 <- phf_codegen 0.8.0 <- # selectors 0.24.0 <- kuchikiki 0.8.8-speedreader <- tauri-utils 2.8.3 # <- tauri-build 2.5.6 <- aeroftp (build-deps) # Used at build-time to generate perfect-hash maps for the HTML parser # used by Tauri's CSP injection. NOT included in the runtime binary. # No exploitation surface in shipped artifacts. "RUSTSEC-2026-0097", # rand 0.7.3 # ---------------------------------------------------------------- # fxhash unmaintained (build-dep only via Tauri stack) # ---------------------------------------------------------------- # `fxhash 0.2.1` <- `selectors 0.24.0` <- `kuchikiki` <- `tauri-utils`. # Build-dependency, not in runtime binary. Same Tauri stack situation. "RUSTSEC-2025-0057", # fxhash # ---------------------------------------------------------------- # Tauri 2.11.0 Origin Confusion (Windows/Android only) - intentional pin # ---------------------------------------------------------------- # GHSA-7gmj-67g7-phm9 / CVE-2026-42184 (CVSS:4.0/AV:N/VI:H) flags Tauri's # `is_local_url()` for accepting `http://.attacker.com/` as a # local origin on Windows and Android, because the check only inspects # the first dot-separated label of the host. An attacker who entices a # user to load such a page can invoke backend IPC commands that the # developer intended to be reachable only from the bundled frontend. # # AeroFTP is NOT reachable through this vector: # # 1. AeroFTP's frontend is always served from the bundled localhost # server via `tauri-plugin-localhost` on `http://localhost:14321`. # We never load remote URLs into the main webview; there is no # `WebviewUrl::External` or `loadUrl` accepting attacker input. # 2. The webview origin is `http://localhost:*`, not a custom scheme # mapped via `http://.localhost/`, so the buggy first-dot # check does not apply to our origin shape. # 3. Linux/macOS builds are not in the affected platform set at all. # # The 2.11.1 fix is incompatible with our localhost-served frontend # because it introduces a stricter `is_local_url()` that classifies # `http://127.0.0.1:*` as remote and rejects every custom command # without a full app ACL manifest. Migrating to 2.11.1 would require # auditing and gating the entire invoke_handler surface behind an ACL # capability scope, which is tracked separately and is unrelated to # this CVE's attack surface. # # The matching pin rationale lives inline on `tauri = "=2.11.0"` in # src-tauri/Cargo.toml lines 44-50. "GHSA-7gmj-67g7-phm9", # Tauri Origin Confusion (not reachable, intentional pin) # ---------------------------------------------------------------- # russh advisories CLEARED by the 0.61.2 bump (no longer ignored) # ---------------------------------------------------------------- # GHSA-wwx6-x28x-8259 (HIGH, post-decompression packet size) and # GHSA-hpv4-5h6f-wqr3 (MEDIUM, server userauth reset), plus the message # field / banner / keyboard-interactive parsing advisories, are all fixed # in russh 0.61.x. We bumped `russh = "0.61.2"` (Cargo.toml:142) once the # 0.61.0/0.61.1 upstream RC-crypto packaging conflict was resolved at # 0.61.2 (see reference-russh-061-unbuildable in memory). No russh advisory # is ignored anymore; the entries were removed in the v4.0.5 cycle. # ---------------------------------------------------------------- # instant 0.1.13 unmaintained (transitive via the AeroVault v4 ECC wrapper) # ---------------------------------------------------------------- # RUSTSEC-2024-0384. `instant` is unmaintained (superseded by `web-time`). # It enters the tree ONLY through the optional ECC error-correction wrapper: # instant 0.1.13 <- parking_lot 0.11.2 <- reed-solomon-erasure 6.0.0 <- aeroftp # `reed-solomon-erasure 6.0.0` pins `parking_lot = "^0.11.2"`, which cannot # resolve to parking_lot 0.12 (the release that dropped `instant`), so the # advisory is not locally fixable without forking the RS crate. # # No security surface: `instant` is a monotonic-clock shim. On AeroFTP's # native desktop targets (Linux/macOS/Windows; never wasm) it compiles to a # thin wrapper over std::time::Instant; the wasm-specific path that carries # any concern is never built. parking_lot uses it only for internal # lock-elapsed bookkeeping, reached exclusively from reed-solomon-erasure's # in-memory parity compute/reconstruct on ECC-enabled vaults. No untrusted # input, no parsing and no crypto decision flows through it. # # Exit path: move to a maintained RS crate (reed-solomon-simd / # reed-solomon-novelpoly) or wait for reed-solomon-erasure to bump parking_lot. # Full evaluation: docs/security-evidence/REED-SOLOMON-ERASURE-EVALUATION-2026-06.md. "RUSTSEC-2024-0384", # instant unmaintained (ECC wrapper via parking_lot 0.11) # ---------------------------------------------------------------- # iroh 1.0 P2P stack - two transitive UNMAINTAINED advisories (peer-l0 normal dependency) # ---------------------------------------------------------------- # The user-to-user P2P drive (T-PEER / AeroShare) links the isolated # `aeroftp-peer-l0` crate as a NORMAL dependency (path = "peer-l0"); WI-3d # promoted it from [dev-dependencies] so the iroh drive engine ships in the # binary (the app drives it via src/peer/). peer-l0 remains the iroh isolation # boundary. It now pulls iroh 1.0 + iroh-blobs 0.103 + iroh-docs 0.101 + # iroh-gossip 0.101 (the 0.92 -> 1.0 migration, 2026-06-26). # # The migration CLEARED the three vulnerability/unsound advisories the 0.92 line # pinned (this is the exit path the earlier evidence doc anticipated): # - RUSTSEC-2026-0118 + RUSTSEC-2026-0119 (hickory-proto DoS): iroh 1.0 resolves # to hickory-proto 0.26.1, which carries both fixes (NSEC3 loop + O(n^2) encode). # - RUSTSEC-2026-0002 (lru IterMut unsound): iroh 1.0's relay stack uses lru # 0.18.0 (patched, >= 0.16.3); the only other lru in the graph is 0.7.8 (via # reed-solomon-erasure), which the advisory marks unaffected (< 0.9.0). The # vulnerable lru 0.13.0 and the pkarr crate are gone from the graph entirely. # iroh 1.0 also dropped stun-rs and pkarr (the Mainline DHT moved to the separate # `iroh-mainline-address-lookup` crate). Full record + per-advisory reachability: # docs/security-evidence/IROH-PEER-L0-ADVISORIES-2026-06.md. # # Only two UNMAINTAINED advisories (NOT vulnerabilities) remain in iroh 1.0's # graph, both compile-time / shim crates with no runtime exploitation surface: # # RUSTSEC-2023-0089 (atomic-polyfill, unmaintained) - an atomics shim reached # via heapless 0.7 <- postcard <- iroh-blobs / iroh-docs <- peer-l0. Not a # vulnerability; a transitive build-block superseded upstream by # `portable-atomic`. (Behind a target-conditional heapless feature, so it # shows only under `cargo tree --target all`, but is in the lock audit reads.) "RUSTSEC-2023-0089", # atomic-polyfill unmaintained (heapless/postcard transitive) # RUSTSEC-2024-0436 (paste, unmaintained) - a compile-time proc-macro reached # in iroh 1.0 via netlink-packet-core <- netdev <- netwatch <- iroh (the old # stun-rs path is gone in 1.0). No runtime surface (proc-macro, build-time # only); superseded by `pastey`. Not a vulnerability. "RUSTSEC-2024-0436", # paste unmaintained (compile-time proc-macro, netwatch path) # ---------------------------------------------------------------- # RUSTSEC-2026-0190 - Unsoundness in n0-error `Error::downcast_mut()` # ---------------------------------------------------------------- # Freshly published to the advisory DB (loaded 2026-06-29), so it lights up # on the first audit after that date independent of any AeroFTP change. It is # an UNSOUNDNESS report (not an exploitable vulnerability): n0-error's # `Error::downcast_mut()` can hand out a `&mut T` of the wrong type under a # specific generic misuse, which is a soundness hole in that helper, not a # remote/attacker-reachable issue. # # n0-error 1.0.0 <- iroh-relay 1.0.0 <- iroh 1.0.0 <- iroh-blobs / iroh-docs # / iroh-mainline-address-lookup <- aeroftp-peer-l0 <- aeroftp # # iroh 1.0.0 pins n0-error 1.0.0 across its whole graph, so there is no # in-tree upgrade until upstream iroh bumps it; AeroFTP never calls # `downcast_mut` on an n0-error and only consumes iroh errors as opaque # `Display` strings on the P2P path. Same accepted-advisory posture as the two # iroh unmaintained ignores above; revisit when iroh ships a fixed n0-error. "RUSTSEC-2026-0190", # n0-error downcast_mut unsoundness (iroh 1.0 transitive, not reachable) # ---------------------------------------------------------------- # RUSTSEC-2026-0194 + RUSTSEC-2026-0195 - quick-xml DoS (< 0.41.0) # ---------------------------------------------------------------- # Two DoS advisories freshly published 2026-06-29 against quick-xml < 0.41.0: # 0194 quadratic run time checking a start tag for duplicate attribute names, # 0195 unbounded namespace-declaration allocation in `NsReader` (memory # exhaustion). Both require attacker-controlled XML fed to the parser to bite. # # The reachable attack surface in AeroFTP is the runtime XML parser: WebDAV, # S3, Azure and STS responses arrive from a possibly-hostile server. That path # is our DIRECT dependency, now bumped to the patched quick-xml 0.41.0 # (src-tauri/Cargo.toml:109). The real surface is fixed. # # The two instances that remain are Tauri-stack transitive and never parse # untrusted remote XML, so they are ignored pending an upstream bump: # # quick-xml 0.37.5 <- tauri-winrt-notification <- notify-rust <- # tauri-plugin-notification <- aeroftp # Windows toast notifications. It parses AeroFTP's OWN toast-template XML # (title/body we build), not remote input, and only on Windows. # # quick-xml 0.39.4 <- plist <- tauri-utils <- tauri(-runtime-wry / codegen) # Info.plist / bundle-metadata parsing at build time and on macOS. It parses # app-owned plist files, not remote input. # # Neither can be bumped without a Tauri-stack release (same posture as the other # Tauri-transitive ignores above). Revisit when Tauri bumps notify-rust / plist. "RUSTSEC-2026-0194", # quick-xml duplicate-attr quadratic DoS (runtime path patched to 0.41; rest Tauri-transitive, app-owned XML) "RUSTSEC-2026-0195", # quick-xml NsReader memory-exhaustion DoS (runtime path patched to 0.41; rest Tauri-transitive, app-owned XML) ] # We do NOT ignore "informational" advisories blanket-style. Each ignore is # a specific RUSTSEC ID with a paragraph explaining the threat-model gap. # Severity: do not blanket-ignore "low" or "informational" — review them. [output] deny = ["unmaintained", "unsound", "yanked"] quiet = false # `vulnerability` is implicitly always denied (advisories[ignore] is the only # escape hatch and every ignored ID is justified above).