#!/usr/bin/env python3 """Parse cargo audit --json output and fail only on unignored vulnerabilities. Avoids the 4MB log overflow that happens when cargo audit prints full dependency trees for every advisory. """ import sys import json IGNORE = { # wasmtime: fix requires rustc 1.91.0+, toolchain pinned to 1.88.0. # We do NOT use Winch backend, Component Model, or 64-bit tables. "RUSTSEC-2026-0006", "RUSTSEC-2026-0020", "RUSTSEC-2026-0021", "RUSTSEC-2026-0085", "RUSTSEC-2026-0086", "RUSTSEC-2026-0087", "RUSTSEC-2026-0088", "RUSTSEC-2026-0089", "RUSTSEC-2026-0091", "RUSTSEC-2026-0092", "RUSTSEC-2026-0093", "RUSTSEC-2026-0094", "RUSTSEC-2026-0095", "RUSTSEC-2026-0096", # rsa: no fixed version available (Marvin Attack) "RUSTSEC-2023-0071", # tracing-subscriber 0.2.x: pulled by arkworks internals only "RUSTSEC-2025-0055", # rustls-webpki: transitive via kube-client, upgrade needs kube ecosystem bump # We do not use CRLs or rely on certificate name constraints in our P2P/RPC stack. "RUSTSEC-2026-0098", "RUSTSEC-2026-0099", "RUSTSEC-2026-0104", # rand: unsound only with custom logger calling rand::rng() during init "RUSTSEC-2026-0097", # lru: Stacked Borrows in IterMut, no user-facing exploit path "RUSTSEC-2026-0002", } data = json.load(sys.stdin) vulns = data.get("vulnerabilities", {}).get("list", []) fail = False for v in vulns: adv = v.get("advisory", {}) pkg = v.get("package", {}) aid = adv.get("id", "") name = pkg.get("name", "?") ver = pkg.get("version", "?") title = adv.get("title", "?") if aid in IGNORE: print(f" [ignored] {aid} {name} {ver}") else: print(f" [FAIL] {aid} {name} {ver} — {title}") fail = True if fail: sys.exit(1) print(f"audit ok — {len(vulns)} advisories checked")