Repository navigation
fix(ci): bump rustls to 0.23.46 and expire the h2 audit exception - #350
Conversation
I bumped rustls to 0.23.46 and chacha20 to 0.10.2 so RUSTSEC-2026-0346 through RUSTSEC-2026-0349 clear and the yanked chacha20 release is gone. I added .cargo/audit.toml for the lone RUSTSEC-2026-0258 exception until 2027-01-15 and taught ci-preflight to print audit JSON, enforce that expiry, and keep scheduled fail-closed behavior for every other advisory (#349).
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
@pullfrog review |
There was a problem hiding this comment.
Hey - I've found 4 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="scripts/ci-preflight.sh" line_range="322" />
<code_context>
+ process.exit(1);
+}
+
const vulnerabilities = report.vulnerabilities || {};
+for (const entry of vulnerabilities.list || []) {
+ const id = entry.advisory?.id;
</code_context>
<issue_to_address>
**Audit can pass without findings**
When `cargo audit` exits 0 but emits valid JSON without a `vulnerabilities` object, `report.vulnerabilities || {}` makes the missing result look empty, so the count logic emits `-1` and `run_cargo_audit_gate` returns success before scheduled fail-closed handling. Nightly publication proceeds without an audit.
Reject reports that lack a valid `vulnerabilities` object before counting findings.
Also at `scripts/ci-preflight.sh:321`.
</issue_to_address>
### Comment 2
<location path="scripts/ci-preflight.sh" line_range="390" />
<code_context>
+ if AUDIT_OUT="$audit_out" node --input-type=commonjs -e '
+const report = JSON.parse(require("fs").readFileSync(process.env.AUDIT_OUT, "utf8"));
+process.exit((report.settings?.ignore || []).includes("RUSTSEC-2026-0258") ? 0 : 1);
+' 2>/dev/null; then
+ ignore_0258=1
+ fi
</code_context>
<issue_to_address>
**Other ignored advisories never expire**
When a different advisory ID is added to the cargo-audit ignore list, the expiry probe checks only `RUSTSEC-2026-0258`, while the report loop merely logs other ignored IDs. Because cargo-audit omits ignored findings from the vulnerability count, scheduled CI passes with those advisories suppressed indefinitely.
Enforce an expiry for every ignored advisory instead of checking only `RUSTSEC-2026-0258`.
Also at `scripts/ci-preflight.sh:332-340`.
</issue_to_address>
### Comment 3
<location path="scripts/ci-preflight.sh" line_range="394" />
<code_context>
+ ignore_0258=1
+ fi
+
+ if [ "$ignore_0258" -eq 1 ] && audit_ignore_is_expired "$(date -u +%Y-%m-%d)" 2027-01-15; then
+ echo 'ci-preflight: cargo audit exception RUSTSEC-2026-0258 expired on 2027-01-15; see #349; re-review the exception' >&2
+ rm -f "$audit_out" "$audit_err"
</code_context>
<issue_to_address>
**Audit exception can outlive deadline**
When the `date` command is unavailable or fails after the exception deadline, `date -u +%Y-%m-%d` failure supplies an empty string to `audit_ignore_is_expired`, which compares it as earlier than the deadline and lets the ignored advisory pass without enforcing expiry.
Validate the date command’s status and `YYYY-MM-DD` output, and fail the gate if either is invalid.
</issue_to_address>
### Comment 4
<location path=".cargo/audit.toml" line_range="6" />
<code_context>
+# enforced by https_client_config_advertises_http11_alpn), so the h2 0.3
+# code path never runs. Upstream fix: tursodatabase/libsql#2224.
+# Tracked in #349. This ignore expires 2027-01-15; ci-preflight fails on
+# that date until the exception is removed or re-reviewed.
+
+[advisories]
</code_context>
<issue_to_address>
**Exception deadline can drift**
When the exception deadline is updated in `.cargo/audit.toml` or documentation but not in the script, when the documented exception deadline is changed without updating the preflight literals, `run_cargo_audit_gate` still enforces the old date and prints it as authoritative, so CI expires the exception too early or permits it beyond its documented deadline.
Keep the deadline in one machine-readable source and have the preflight read it, or add a test that asserts the documented and enforced deadlines stay identical.
Also at `scripts/ci-preflight.sh:394-395`.
</issue_to_address>Sourcery assessment
Needs a human reviewer. 4 findings to address first, and if the h2 advisory affects a reachable code path despite the HTTP/1.1 assumption, this exception lets scheduled audits pass and may allow affected releases to be published until it expires. Reverting restores the audit gate, but cannot retract artifacts already published.
Blocking findings: scripts/ci-preflight.sh:322, scripts/ci-preflight.sh:390, scripts/ci-preflight.sh:394, .cargo/audit.toml:6
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes across all seven files, including dependency updates, the scoped h2 exception, and audit-gate behavior.
- Dependency fixes: Updates
rustlsto0.23.46andchacha20to0.10.2; published checksums, Rust requirements, and RustSec patched-version ranges match. - Time-bounded exception: Ignores only
RUSTSEC-2026-0258, documents the HTTP/1.1-only transport rationale and #349, and rejects the exception from 2027-01-15 UTC onward. - Audit reporting: Prints advisory and warning details, parses successful JSON reports, and preserves scheduled fail-closed behavior and operational-error failures, with corresponding documentation and expiry self-check coverage.
Validation passed: bash scripts/ci-preflight-test.sh, node scripts/ci-workflow-test.mjs, shell syntax checks, and 15 additional cases exercising the production audit-gate functions with simulated cargo-audit output and dates. Verified the pinned cargo-audit JSON contract and libsql/Hyper transport behavior against upstream source. Full Rust preflight and real cargo-audit/cargo-deny were not rerun locally; the PR's supply-chain CI lane passed, while its Rust lane was still pending at review time.
gpt-6.1-sol | 𝕏
|
@pullfrog review |
There was a problem hiding this comment.
Important
Expiry-file validation can fail without failing the audit gate. One reproducible finding is inline.
Reviewed changes across all eight files, covering the dependency updates, audit exception policy, report classification, and regression checks.
- Dependency updates: Bumps
rustlsto0.23.46andchacha20to0.10.2without changing manifests or theh2versions. - Expiring exceptions: Adds the scoped
RUSTSEC-2026-0258ignore, machine-readable UTC deadlines, and checks intended to cover every effective ignored advisory, with corresponding policy documentation. - Audit classification: Parses successful and failing JSON reports, logs advisory and warning details, and preserves separate scheduled fail-closed and ordinary non-blocking advisory paths.
- Verification: Preflight helper/self-check tests, CI workflow contracts, and shell syntax checks passed. Additional probes against the production functions reproduced the inline issue; valid and expired controls behaved correctly. Full Rust preflight and real
cargo-audit/cargo-denywere not rerun locally. The PR's supply-chain check passed; Rust and remote-database checks were still running when inspected.
gpt-6.1-sol | 𝕏
The expiry parser's failure was hidden by process substitution, so a duplicate id, a bad line, or an invalid date after a valid prefix still let the gate succeed. Parsing now has to succeed before any deadline is used, and the self-check covers those files in both fail-closed modes.
|
@pullfrog review |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes across all eight files and three commits, including the latest expiry-parser fix and the complete supply-chain policy changes.
- Dependency updates: Bumps
rustlsto0.23.46andchacha20to0.10.2; published checksums, Rust requirements, and RustSec patched-version ranges match. - Expiring exceptions: Adds the scoped
RUSTSEC-2026-0258exception tracked in #349, requires a valid UTC deadline for every effective ignored advisory, and documents the HTTP/1.1 transport rationale. - Audit classification: Reports advisories and warnings while preserving non-blocking ordinary advisory reports, scheduled fail-closed behavior, and operational-error failures; verified the effective-ignore JSON contract against pinned
cargo-auditsource. - Parser regression:
121f6bdchecks the expiry parser's actual status before consuming its output; duplicate IDs, malformed trailing lines, and invalid dates now reject the entire file in both modes. Verified and resolved the prior review thread. - Verification: Preflight helper/self-check tests, CI workflow contracts, shell syntax checks, and 20 additional production-gate probes passed. The probes simulate cargo-audit output and dates, not live provider behavior. Full Rust preflight and real
cargo-audit/cargo-denywere not rerun locally; the PR's supply-chain and remote-database checks passed, while Rust checks remained in progress when inspected.
gpt-6.1-sol | 𝕏

The scheduled supply-chain check failed closed on rustls 0.23.45. That was RUSTSEC-2026-0346, RUSTSEC-2026-0347, RUSTSEC-2026-0348, and RUSTSEC-2026-0349, which are fixed in rustls 0.23.46. The same run also warned that chacha20 0.10.1 is yanked.
I bumped only those two crates in Cargo.lock: rustls to 0.23.46 and chacha20 to 0.10.2. h2 0.3.27 and h2 0.4.19 are unchanged. I did not edit Cargo.toml, patch sources, or vendor trees.
The preflight now prints each advisory id, crate, and version from the cargo-audit JSON, and it prints yanked and unmaintained warnings from that same report. Scheduled runs still fail closed when an advisory is listed. Pull requests and ordinary main pushes still do not. Operational audit failures still fail the job.
RUSTSEC-2026-0258 is h2 0.3.27, and there is no fixed 0.3 release. I ignore that one advisory in
.cargo/audit.toml. The libsql remote connector only offers HTTP/1.1 (src/remote_https.rs, enforced byhttps_client_config_advertises_http11_alpn), so the h2 0.3 code path never runs. The upstream fix is tursodatabase/libsql#2224. I am tracking the exception in #349. cargo-audit has no expiry field, so the preflight fails on 2027-01-15 UTC while that ignore is still present and tells me to re-review it. The message names the advisory id, the date, and #349.Validation
bash scripts/ci-preflight.sh --audit-expiry-self-checkbash scripts/ci-preflight-test.shcargo fmt --all --checkbash scripts/ci-preflight.sh --only supply-chainwithJMODGUARD_AUDIT_FAIL_CLOSED=1and again without itBoth supply-chain runs passed. Each printed
ci-preflight: advisory RUSTSEC-2026-0258 ignored (expires 2027-01-15; see #349)and no other advisory.cargo deny check bans licenses sourcesreported bans, licenses, and sources ok, andcargo update --workspace --lockedlocked 0 packages. I also checked the gate against parse failures, an empty report, a JSON report that still lists advisories when cargo exits 0, the expiry date before, on, and after 2027-01-15, the fail-open path, and warnings that must not change the exit code.Reviewed commit: 610e46b
Summary by Sourcery
Harden supply-chain auditing by updating vulnerable dependencies and adding expiring advisory-exception enforcement.
Bug Fixes:
Enhancements:
CI:
Documentation:
Review round 1
jatmn's PR Review agent:
.cargo/audit-expiries, and preflight fails on that date..cargo/audit-expiries, and the self-check requires the docs to match it.Reviewed commit: 121f6bd
Summary by Sourcery
Harden supply-chain CI by updating affected dependencies and enforcing an expiring, documented exception for the unfixable h2 advisory.
Bug Fixes:
Enhancements:
CI:
Documentation:
Tests: