GHSA-g9hv-x236-4qp3: Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
Summary
A malicious SSH server can crash a russh client session with a single
malformed key-exchange reply, causing a pre-authentication Denial-of-Service
before the server host key is verified. The embedding process itself stays
up, but the connection is killed deterministically.
Details
Every *other* kex path in russh validates the peer ephemeral length before
cloning:
- Curve25519Kex::server_dh (russh/src/kex/curve25519.rs:61-65) checks
if pubkey_len != 32 { return Err(crate::Error::Kex); } before
clone_from_slice.
- The hybrid ML-KEM, ECDH-NIST, and DH/GEX paths all validate lengths.
Only the client-side curve25519 compute_shared_secret is missing the check.
This asymmetric validation gap makes the bug easy to miss in code review: a
malicious *client* cannot panic a russh server this way (the server path
checks the length), but a malicious *server* can panic a russh client.
Incriminated source code (repo-relative paths):
- Vulnerable compute_shared_secret: russh/src/kex/curve25519.rs:110-117 (panic at line 113)
- Client-side entry point: russh/src/client/kex.rs:266-277 (KEX_ECDH_REPLY → Bytes::decode → compute_shared_secret)
- Server-side contrast (has the length check): russh/src/kex/curve25519.rs:51-88 (server_dh)
- Session spawn site: russh/src/client/mod.rs (connect_stream → russh_util::runtime::spawn)
- Runtime wrapper: russh-util/src/runtime.rs:37-48 (spawn wraps tokio::spawn; panic surfaces as JoinError)
PoC
A standalone, self-contained Cargo PoC is provided in
vuln_poc/vuln_002_client_wronglen_x25519_panic/ in this repo. It installs a
global panic hook that sets an AtomicBool if any panic fires, starts a
malicious raw SSH server on 127.0.0.1:0 that completes the SSH id and
KEXINIT exchange, reads the client KEX_ECDH_INIT, and sends
KEX_ECDH_REPLY with a 16-byte server ephemeral (instead of 32) and a fake
signature. It then calls russh::client::connect with Preferred::kex set
to curve25519-sha256 and a handler that accepts any server key (the check
Details
Original advisory: https://github.com/advisories/GHSA-g9hv-x236-4qp3
More from GitHub Security Advisories
- mediumGHSA-jr6p-8pjj-mfx6: Capsule has an incomplete fix of CVE-2026-22872: TenantResource RawItems and Generators s…2026-07-31
- mediumGHSA-68cj-mvg9-rgm2: Capsule: CapsuleConfiguration NodeMetadata regex fields lack webhook validation, allowing…2026-07-31
- mediumGHSA-ff84-5f28-78qj: re2: Out-of-bounds heap read in `exec`/`test`/`match` via attacker-influenced `lastIndex`…2026-07-31
- mediumGHSA-6hxr-mr5r-9836: re2: Global `String.prototype.match` with an empty-matchable pattern never advances → inf…2026-07-31
- mediumGHSA-x83g-979r-f5fh: Sylius Mollie Plugin has unauthenticated IDOR that leaks order token and customer PII2026-07-31