
Cloud Vulnerability DB
A community-led vulnerabilities database
CVE-2026-128087 is a callback ordering vulnerability in the russh Rust SSH client/server library, where client::Handler::kex_done() is invoked with the raw key-exchange shared secret before check_server_key() verifies the server's host key or certificate. This affects russh versions >= 0.55.0 and < 0.65.1, introduced when the kex_done callback was added in commit 500bef1. The vulnerability was published on November 3, 2026, and assigned a CVSS v3.1 base score of 3.7 (Low) (Github Advisory, Feedly).
The root cause is an incorrect behavior order (CWE-696) combined with incorrect authorization (CWE-863) and key exchange without entity authentication (CWE-322). In russh/src/client/mod.rs, the library calls kex_done() immediately after the server proves cryptographic possession of its presented host key, but before the application's check_server_key() callback decides whether that key belongs to the intended server. Because any attacker-controlled SSH server can produce a valid KEX signature with its own key, cryptographic verification of the KEX does not establish peer identity — only check_server_key() does. Applications that override kex_done() to derive secondary channel keys, initialize VPN-over-SSH transports, or perform other protocol-bridging actions are therefore exposed to premature callback execution by a rogue server (Github Advisory, russh PR #808).
An unauthenticated attacker who can impersonate or intercept the SSH endpoint targeted by a vulnerable russh client can trigger the application's kex_done() callback — and any secondary-channel initialization or key derivation it performs — before the connection is rejected via UnknownKey. The practical impact depends entirely on the application's callback implementation: applications using kex_done() for VPN-over-SSH, UDP data planes, file transfer, or custom enterprise transports may expose early secondary-channel data or establish state with an untrusted peer. Confidentiality is the primary concern (low impact per CVSS); integrity and availability are not directly affected. Clients that leave kex_done() at its no-op default are not affected (Github Advisory).
A self-contained proof-of-concept (PoC) written in Rust is publicly available in the GitHub Security Advisory, demonstrating that kex_done() fires before check_server_key() rejects an untrusted host key (Github Advisory). The PoC is classified as poc_code with high confidence by Feedly's exploit analysis, though it only demonstrates the ordering bug against a local server and does not compromise a real system. Exploitation requires the attacker to control or impersonate the SSH endpoint the client connects to (high attack complexity), and the client application must override kex_done() with security-sensitive logic. There is no evidence of in-the-wild exploitation, no threat actor attribution, and the EPSS score is 0.0. The vulnerability is not listed in the CISA KEV catalog (Feedly).
client::Handler::kex_done() to perform security-sensitive actions such as deriving secondary channel keys or initializing a VPN/data-plane transport.kex_done() with the raw shared secret before calling check_server_key(). Any application logic in kex_done() — such as exporting the shared secret or initializing a secondary channel — executes at this point.russh::Error::UnknownKey when check_server_key() rejects the rogue host key, but the attacker has already triggered the application's callback and any associated side effects (Github Advisory).kex_done callback execution followed immediately by a connection failure or UnknownKey error; SSH client logs indicating repeated connection attempts to endpoints with unrecognized host keys.Upgrade russh to version 0.65.1 or later, which fixes the ordering bug by moving the kex_done() call to after check_server_key() has accepted the server identity for the initial key exchange (russh v0.65.1 Release, russh PR #808). The fix was merged in commit 43a46d6. As a short-term workaround for applications that cannot immediately upgrade, developers should audit their kex_done() implementations and add an independent server identity check within the callback before taking any security-sensitive action, or defer all callback-derived actions until host trust is confirmed through another mechanism (Github Advisory).
The vulnerability was reported by researcher Yeaseen and published by the russh maintainer (Eugeny) on November 3, 2026, with the fix merged the same day via PR #808. The maintainer acknowledged and merged the fix promptly, noting the security fix in the v0.65.1 release notes alongside several other bug fixes (russh v0.65.1 Release). No significant broader media coverage or notable community debate has been identified beyond the advisory and associated pull request.
Fix availability across major Linux distributions and their releases.
Source: This report was generated using AI
Free Vulnerability Assessment
Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.
Get a personalized demo
"Best User Experience I have ever seen, provides full visibility to cloud workloads."
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
"We know that if Wiz identifies something as critical, it actually is."