From 93c474e84b2eeee147c274f3d75f48e5ea42d0d5 Mon Sep 17 00:00:00 2001 From: Tejas Chopra Date: Wed, 19 Aug 2026 14:19:46 -0700 Subject: [PATCH] fix(deps): clear the two Rust advisories and make cargo audit blocking (#3121) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description An independent OSV sweep of every locked package in the repo (1,463 across PyPI, crates.io and npm) surfaced three RUSTSEC advisories that **no gate was reporting**: | advisory | package | status | |---|---|---| | RUSTSEC-2026-0258 (GHSA-q83h-524g-xf6h) | h2 0.4.15 | fixed here → 0.4.16 | | RUSTSEC-2026-0204 | crossbeam-epoch 0.9.18 | fixed here → 0.9.20 | | RUSTSEC-2024-0436 | paste 1.0.15 | unmaintained, **no patched version exists** | **h2 is the one that matters.** It accepted and queued empty DATA frames without limit; a peer that never drains a stream drives unbounded memory growth, or a panic when the length overflows. It is not a corner of the tree — it reaches the published wheel (`hf-hub -> headroom-core -> headroom-py`) and the entire axum/reqwest/aws-config surface of `headroom-proxy`. **Why none of this was visible** is the more important half of this PR. The `audit` job was already correct in one respect I initially misread — the `rust-changes` job reports `rust=true` for `schedule`, so it *does* run nightly rather than only on Rust changes. The actual defect is that `cargo audit` was `continue-on-error: true`. It has been faithfully reporting findings into a green run that nobody looks at. Two of the three are also invisible to Dependabot entirely: `crossbeam-epoch` and `paste` are RUSTSEC-only with no GHSA, so the advisory database GitHub scans does not contain them. This job is their only possible coverage. ## Type of Change - [x] Bug fix (non-breaking change that fixes an issue) ## Changes Made - `Cargo.lock`: `h2` 0.4.15 → 0.4.16, `crossbeam-epoch` 0.9.18 → 0.9.20. Version + checksum only, 4 lines each way. - `.github/workflows/rust.yml`: dropped `continue-on-error: true` from the `cargo audit` step. `cargo deny check licenses` is deliberately left soft-fail — `deny.toml` documents itself as intentionally permissive for now, and tightening license policy is a separate decision. - `.cargo/audit.toml` (new): lists `RUSTSEC-2024-0436` as accepted, with the reason. Path matters — cargo-audit reads `.cargo/audit.toml`; a root-level `audit.toml` is silently ignored. `paste` is unmaintained rather than vulnerable, and there is nothing to move to. It arrives via `tokenizers -> paste` and `rav1e -> paste`, both under `fastembed`, so it is not actionable at our layer. Worth revisiting when `tokenizers` adopts `pastey`. ## Testing - [x] Manual testing performed ### Test Output ```text Checksums verified against the real crates.io tarballs, not just the API field: OK h2 0.4.16 (173331 bytes) lock : a9f37a958b41b3b19ee2707c06439c0e9e547e847223eb791ecb0cb821c65e27 real : a9f37a958b41b3b19ee2707c06439c0e9e547e847223eb791ecb0cb821c65e27 OK crossbeam-epoch 0.9.20 (47545 bytes) lock : 2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f real : 2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f Dependency-set equality (crates.io API, kind=normal): h2 0.4.15 -> 0.4.16 : 11 deps before, 11 after, identical crossbeam-epoch 0.9.18 -> .20: 2 deps before, 2 after, identical ``` ## Real Behavior Proof - Environment: macOS (darwin 25.4.0), worktree off `main` @ `b77d6129`. **`cargo` is not installed on this machine** — see below. - Exact command / steps: (1) parsed `uv.lock`, `Cargo.lock` and all four `package-lock.json` files into 1,463 unique (ecosystem, name, version) tuples and queried `api.osv.dev/v1/querybatch`, then pulled full records for every hit; (2) walked `Cargo.lock` to find which workspace crates actually reach `h2`, `crossbeam-epoch` and `paste`; (3) fetched both crates' dependency lists from the crates.io API at the old and new versions and compared them; (4) downloaded both `.crate` tarballs and computed SHA-256 locally. - Observed result: both bumps are patch-level with **byte-identical dependency sets**, so the edited `Cargo.lock` is exactly what `cargo update -p h2 -p crossbeam-epoch` would produce, and both checksums match the real tarballs. `h2` 0.4.16 was published 2026-08-17, which is also why Dependabot has not raised it yet. - Not tested: I could not run `cargo audit`, `cargo build` or the test suite locally — cargo is not installed here. **The lock edit is hand-written, so CI is the real verification**, and it is well covered: the `rust` workflow's `test`, `build`, `parity` and now-blocking `audit` jobs all consume this lock and will fail on a bad checksum or an unresolvable graph. I would not merge this on green-by-assertion; it needs the `rust` jobs actually green. ## Runtime Rollout Safety - Rollout-managed feature(s): None. - Minimum rollout channel: n/a - Stable/default behavior changed: No runtime behavior changes. CI becomes stricter: `cargo audit` can now fail a build. - Kill switch / disable path: re-adding `continue-on-error: true` restores the previous (useless) behavior. - Unsafe override required: No. - Qualification impact: A newly-disclosed RUSTSEC advisory will now turn the nightly Rust run red instead of being silently absorbed. That is the intent, but it does mean advisories become someone's problem on disclosure day — the escape hatch is a documented entry in `.cargo/audit.toml`. - Rollback path: Revert the commit. ## Review Readiness - [x] I have performed a self-review - [x] This PR is ready for human review ## Additional Notes Deliberately **not** bundled here, each worth its own change: - **`npm` has no audit gate at all** — no `npm audit` anywhere in `.github/`. Current npm exposure is only `nanoid` 3.3.17 (GHSA-2v37-7h3g-55p8) in three lockfiles, all `dev: true`, which GitHub auto-dismissed correctly. Low stakes today, but the gate is absent rather than passing. - **`pip-audit` only audits `--extra all`**, which excludes the integration extras (`crewai`, `agno`, `autogen`, `langchain`, `strands`, `bedrock`, `memory-stack`, `sandbox`). Every Python advisory currently open against this repo lives in exactly that blind spot — GitPython via `agno` (#3120), chromadb and json-repair via `crewai`. Dependabot catches them because it scans the whole lock; the CI gate structurally cannot. - **Dependabot's `docker` ecosystem is configured for `directory: /` only**, so the five non-root Dockerfiles get no base-image updates. Co-authored-by: Tejas Chopra --- .cargo/audit.toml | 23 +++++++++++++++++++++++ .github/workflows/rust.yml | 8 ++++++-- Cargo.lock | 8 ++++---- 3 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 .cargo/audit.toml diff --git a/.cargo/audit.toml b/.cargo/audit.toml new file mode 100644 index 000000000..e8a321e36 --- /dev/null +++ b/.cargo/audit.toml @@ -0,0 +1,23 @@ +# cargo-audit configuration for the Rust workspace. +# +# Path matters: cargo-audit reads `.cargo/audit.toml`, not a root-level +# `audit.toml`. A file at the repo root is silently ignored. +# +# The `audit` job in .github/workflows/rust.yml is a BLOCKING gate. It runs on +# every PR touching Rust and nightly on the schedule (the `rust-changes` job +# reports `rust=true` for `schedule`/`workflow_dispatch`, so a newly-disclosed +# advisory surfaces without anyone touching Rust code). +# +# It was `continue-on-error: true` until the change that added this file, which meant it reported findings +# nobody saw: RUSTSEC-2026-0258 (h2, unbounded empty DATA frames) sat in a green +# run. Anything ignored here has to be listed explicitly, with a reason. + +[advisories] +ignore = [ + # `paste` is unmaintained — an advisory of project status, not a + # vulnerability; there is no patched version to move to. It is transitive + # and unavoidable at our layer: tokenizers -> paste and rav1e -> paste, + # both reached via fastembed. Re-evaluate when tokenizers moves to + # `pastey` (the maintained drop-in fork). + "RUSTSEC-2024-0436", +] diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index e14ef49d1..ce9d173ea 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -224,8 +224,12 @@ jobs: uses: taiki-e/install-action@v2 with: tool: cargo-audit,cargo-deny - - name: cargo audit (soft-fail) - continue-on-error: true + # Blocking. Soft-failing this made it useless: RUSTSEC-2026-0258 (h2, + # unbounded empty DATA frames -> unbounded memory or a panic) was + # reported by this job for as long as it existed and never turned a run + # red, so nobody acted on it. Accepted advisories go in audit.toml with + # a written reason rather than being swallowed wholesale here. + - name: cargo audit run: cargo audit - name: cargo deny check licenses continue-on-error: true diff --git a/Cargo.lock b/Cargo.lock index bfe188254..fe0ddb991 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1209,9 +1209,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.18" +version = "0.9.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" dependencies = [ "crossbeam-utils", ] @@ -1805,9 +1805,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.15" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155" +checksum = "a9f37a958b41b3b19ee2707c06439c0e9e547e847223eb791ecb0cb821c65e27" dependencies = [ "atomic-waker", "bytes",