Skip to content

fix(deps): bump rust-dependencies group, taking russh 0.63.1 security fixes - #2365

Merged
chaliy merged 1 commit into
mainfrom
claude/pensive-hypatia-42c9y1
Aug 31, 2026
Merged

fix(deps): bump rust-dependencies group, taking russh 0.63.1 security fixes#2365
chaliy merged 1 commit into
mainfrom
claude/pensive-hypatia-42c9y1

Conversation

@chaliy

@chaliy chaliy commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

What changed

Takes the rust-dependencies group bump that Dependabot opened as #2360 (flate2
1.1.9→1.1.10, napi 3.12.1→3.12.2, syn 3.0.3→3.0.4, russh 0.62.7→0.63.1) and adds the
code change russh 0.63 requires, which #2360 could not make on its own.

russh 0.63.1 is a security release for code we actually run as an SSH client:

  • GHSA-47hw-gvq5-r2gm — client-side Handler callbacks were reachable with invalid
    (never-opened) channel IDs. This is the client-side mirror of GHSA-m65r-rprj-r5rg.
  • GHSA-p8qx-h547-fjw9 — two peers disagreeing on supported MACs could negotiate none
    MAC for a cipher that requires one, panicking the session task.

It also carries stricter kex checks, a PKCS#8 parsing panic fix, constant-time agent
unlock, and Curve25519 parameter sanitization.

Neither GHSA is in the RustSec advisory database yet, so cargo audit is green on main
today despite russh 0.62.7 being affected. The bump is what fixes it; our audit tooling
would not have told us.

Behavior change — SSH host certificates. russh 0.63 widened
Handler::check_server_key to receive a PublicKeyOrCertificate, so a server can now
present a CA-signed host certificate instead of a raw key. Bashkit has no CA trust store,
so under strict_host_key_checking (the default) a certificate is rejected — including
when the public key it wraps is itself a configured trusted key. Matching the embedded key
would extend trust on the strength of a signature chain we never validated, and would
ignore the certificate's validity window, principals and critical options. Configuring the
host's public key directly stays the supported path. Non-strict mode is unchanged: it still
accepts anything after warning.

Recorded as L-SSH-001 in knowledge/operations/limitations.md, with TM-SSH-006 updated
in both the knowledge threat model and the user-facing rustdoc one.

Why

Dependabot #2360 was red on five checks. It bumped russh across a breaking 0.x boundary
without the adaptation, so the crate did not compile:

error[E0053]: method `check_server_key` has an incompatible type for trait
  --> crates/bashkit/src/builtins/ssh/russh_handler.rs:39:28
   |
39 |         server_public_key: &russh::keys::PublicKey,
   |                            ^^^^^^^^^^^^^^^^^^^^^^^ expected `russh::keys::PublicKeyOrCertificate`,
   |                                                    found `russh::keys::PublicKey`

and cargo vet had six unvetted new versions.

Before / After

Before — on #2360's head (ac9cb47):

Check    failure     Lint     failure     Test     failure
Examples failure     Audit    failure
Vetting Failed!
6 unvetted dependencies:
  flate2:1.1.10  miniz_oxide:0.9.1  napi:3.12.2
  russh:0.63.1   syn:3.0.4          zlib-rs:0.6.7

After — locally on this branch:

$ cargo test -p bashkit --features ssh --lib builtins::ssh::russh_handler
test result: ok. 16 passed; 0 failed; 0 ignored; 2692 filtered out

$ cargo vet --locked
Vetting Succeeded (27 fully audited, 5 partially audited, 587 exempted)

$ cargo clippy --all-targets --features http_client,ssh,sqlite -- -D warnings
Finished `dev` profile

$ cargo fmt --check && just check-okf && just check-doc-links
knowledge: OKF v0.2 conformant (40 concepts, 7 index files, 1 log file)
docs OK: 157 relative links and 6 dependency versions across 45 files

Five new host-key tests cover the decision, the important one being that a certificate is
refused even when the key it certifies is trusted:

test_strict_accepts_matching_public_key ... ok
test_strict_rejects_unmatched_public_key ... ok
test_strict_rejects_certificate_even_when_inner_key_is_trusted ... ok
test_strict_rejects_certificate_with_wildcard_host ... ok
test_non_strict_accepts_certificate ... ok

The certificate fixture is a real OpenSSH ed25519 host certificate (an ssh-key crate test
vector), not a hand-rolled blob.

Risk

  • Medium. Touches SSH host-key verification, a security boundary.
  • The certificate path is new surface that russh 0.62 could never reach, so nothing that
    worked before stops working — a deployment relying on certificate-based host keys would
    have been failing already.
  • supply-chain/ changes come from cargo vet regenerate exemptions. Beyond the six
    version bumps it also pruned nine exemptions now covered by a refreshed Mozilla import
    (anstream, anstyle-parse, anstyle-query, anstyle-wincon, colorchoice,
    is_terminal_polyfill, once_cell_polyfill, simdutf8, strsim) and added the
    corresponding simdutf8 audit to imports.lock. These are coupled: the prune is only
    valid because of the import.
  • russh 0.62.7→0.63.1 is recorded as an exemption, not a delta audit. The existing
    russh deltas in audits.toml are human review attestations, and I am not in a position
    to sign one. If you want this version genuinely audited, that is a follow-up:
    just vet-certify russh 0.63.1.

Checklist

  • Tests added or updated
  • Backward compatibility considered

Generated by Claude Code

… fixes

Supersedes the Dependabot group bump in #2360, which could not compile:
russh 0.63 changed Handler::check_server_key to take PublicKeyOrCertificate
instead of &PublicKey, and cargo-vet had six unvetted new versions.

russh 0.63.1 is a security release for the client path we use:
  - GHSA-47hw-gvq5-r2gm: client-side Handler callbacks reachable with
    invalid (never-opened) channel IDs
  - GHSA-p8qx-h547-fjw9: MAC-requiring cipher negotiable without a MAC,
    panicking the session task
Neither advisory is in the RustSec database yet, so cargo-audit reports
clean on main despite russh 0.62.7 being affected.

Host certificates are a new surface russh 0.62 could never deliver. With
no CA trust store there is nothing to validate a certificate against, so
strict mode rejects them - including when the key a certificate wraps is
itself trusted, since matching that would extend trust on the strength of
an unvalidated signature chain and ignore the certificate's validity
window, principals and critical options. Recorded as L-SSH-001.

Also bumps flate2 1.1.9 -> 1.1.10, napi 3.12.1 -> 3.12.2, syn 3.0.3 ->
3.0.4. supply-chain/ regenerated via `cargo vet regenerate exemptions`,
which additionally pruned nine exemptions now covered by a refreshed
Mozilla import.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 31, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
bashkit 921dde7 Commit Preview URL

Branch Preview URL
Aug 31 2026, 09:25 PM

@chaliy
chaliy merged commit 06c255b into main Aug 31, 2026
47 checks passed
@chaliy
chaliy deleted the claude/pensive-hypatia-42c9y1 branch August 31, 2026 21:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant