diff --git a/.cargo/audit.toml b/.cargo/audit.toml new file mode 100644 index 0000000..591d3b5 --- /dev/null +++ b/.cargo/audit.toml @@ -0,0 +1,37 @@ +# cargo-audit configuration. cargo-audit reads it from the current directory +# only, so run scripts/audit.sh from anywhere: it audits every Cargo.lock in the +# repo (the runtime and each connector) from the root, against this one list. + +[advisories] +ignore = [ + # rustls 0.22.4 and rustls-webpki 0.102.8 come with the sync `nats` 0.25 + # client (core, connectors/amqp, connectors/mq); connectors/amqp also uses + # rustls 0.22 directly for amqps://. nats 0.25 is the last release of the + # sync client, so this line gets no patched version; moving to async-nats + # removes all six. Ignores go by advisory ID, so these would also hide + # 0346/0349 on rustls 0.23: keep core on >= 0.23.46. + # None is reachable the way the crates are used here: + + # Debug output of client session values leaks secrets only through a + # custom ClientSessionStore; neither nats nor vejas-amqp installs one. + "RUSTSEC-2026-0346", + # An unauthenticated ServerHello can drop later connections from hybrid + # post-quantum to classical key exchange. rustls 0.22 on ring never offers + # a post-quantum group, so there is nothing to downgrade. + "RUSTSEC-2026-0349", + # CRL distribution-point matching and CRL parsing: no CRL is ever loaded. + "RUSTSEC-2026-0049", + "RUSTSEC-2026-0104", + # URI and wildcard name constraints: reachable only after signature + # verification, with a certificate misissued by a CA the client already + # trusts, and only on a TLS connection (a nats:// URL to a server that does + # not require TLS stays plaintext). + "RUSTSEC-2026-0098", + "RUSTSEC-2026-0099", + + # idna 0.1.5 accepts Punycode labels that decode to plain ASCII. It comes + # through url 1.7 <- amq-protocol 1.4 <- amiquip 0.4.2 (the last amiquip + # release), in connectors/amqp only, where it parses the broker URL the + # operator configures, never untrusted input. Leaves with amiquip. + "RUSTSEC-2024-0421", +] diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml new file mode 100644 index 0000000..e8e07ef --- /dev/null +++ b/.github/workflows/audit.yml @@ -0,0 +1,21 @@ +name: audit + +# Every Cargo.lock in the repo against the RustSec advisory database. Daily as +# well as on push: advisories are published without any commit here. +on: + push: + branches: [master] + pull_request: + schedule: + - cron: '23 5 * * *' + workflow_dispatch: + +jobs: + audit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install cargo-audit + run: cargo install cargo-audit --locked + - name: Audit the runtime and every connector + run: scripts/audit.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index a3a2aad..31d8f61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,19 @@ is `0`, minor versions may carry breaking changes — they are called out here. `docker run IMAGE vejas-runtime --version` stayed up instead of answering. `e2e/detect` D3 checks it. +### Security +- **rustls 0.23.43 → 0.23.46** in the runtime, for RUSTSEC-2026-0285 (TLS 1.3 + handshake messages accepted across encryption levels), -0346, -0348 and + -0349. rustls is the TLS stack of the runtime's HTTP client (http-poll, + oauth-poll, webhooks, Vault) and of MQTT over TLS. +- **Dependency advisories are checked in CI.** `scripts/audit.sh` runs + cargo-audit on every `Cargo.lock` in the repo, the runtime and each + connector, on every push and once a day. Six advisories against rustls 0.22 + and rustls-webpki 0.102 remain: they come with the sync `nats` 0.25 client, + which has no patched release, and moving to async-nats removes them. + `.cargo/audit.toml` lists them with the reason none is reachable here, as + well as idna 0.1.5 in the AMQP connector (via amiquip). + ## [0.3.5] — 2026-09-24 ### Changed — no cliff past ten thousand open correlations (varpulis #289) diff --git a/core/Cargo.lock b/core/Cargo.lock index 106e14b..0e9bbd5 100644 --- a/core/Cargo.lock +++ b/core/Cargo.lock @@ -1337,9 +1337,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.43" +version = "0.23.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" +checksum = "48e13bd8c0e9365c43cfa5c9e8f9ad49d3c8444926c9aac819e0e4dc503c8fdf" dependencies = [ "log", "once_cell", @@ -1819,7 +1819,7 @@ dependencies = [ "flate2", "log", "once_cell", - "rustls 0.23.43", + "rustls 0.23.46", "rustls-pki-types", "url", "webpki-roots 0.26.11", @@ -1980,7 +1980,7 @@ version = "0.3.5" dependencies = [ "ctrlc", "nats", - "rustls 0.23.43", + "rustls 0.23.46", "serde_json", "tiny_http", "ureq", diff --git a/scripts/audit.sh b/scripts/audit.sh new file mode 100755 index 0000000..dadd459 --- /dev/null +++ b/scripts/audit.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# Audit every Cargo.lock in the repo against the RustSec advisory database. +# +# The runtime (core/) and each connector crate carry their own lockfile, and +# cargo-audit reads .cargo/audit.toml from the current directory only, so this +# runs from the repo root with --file for each lock: one ignore list for all. +# CI runs it on every push and once a day, since advisories land without any +# commit here (.github/workflows/audit.yml). +set -euo pipefail +cd "$(dirname "$0")/.." + +fail=0 +while IFS= read -r lock; do + echo "[audit] $lock" + cargo audit --file "$lock" || fail=1 +done < <(git ls-files '*Cargo.lock') +exit $fail