Advisories for Cargo/Russh package

2026

Russh: Channel-scoped server callbacks can be reached without an open channel

There is a server-side channel state issue in russh. After a client is authenticated, russh can dispatch channel-scoped handler callbacks for recipient channel IDs that were never opened or confirmed. In the strongest reproduced case, the client does not send SSH_MSG_CHANNEL_OPEN at all. It authenticates normally, then sends SSH_MSG_CHANNEL_REQUEST packets with request type exec for a range of recipient channel IDs. russh still calls the server application's exec_request handler. This …

Russh: Pre-auth remote panic via all-zero Curve25519 peer public value (encode_mpint OOB)

A pre-authentication denial-of-service panic in russh 0.62.2 (commit c4be19f1915c8682f4615c3fd50008512b474491, current default branch main as of 2026-07-22). An unauthenticated client sends a single SSH_MSG_KEX_ECDH_INIT whose Q_C is 32 zero bytes. russh's Curve25519 KEX does not reject the all-zero peer public value, so server_dh() computes the all-zero shared secret and compute_exchange_hash() then calls encode_mpint(&shared.0, …), which indexes s[i] at i == s.len() and panics (index out of bounds: the len is 32 …

Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records

A post-authentication denial-of-service panic in russh 0.62.2 (commit c4be19f1915c8682f4615c3fd50008512b474491, current default branch main as of 2026-07-22). An authenticated client sends a pty-req channel request carrying more than 130 terminal-mode records. The parser uses a fixed [(Pty::TTY_OP_END, 0); 130] array but increments its counter i for every valid record (logging "too many pty codes" without returning), then slices &modes[0..i] — an out-of-bounds slice that panics (range end index 131 out of …

Russh: Unchecked keyboard-interactive prompt count in client auth path

In the russh client keyboard-interactive authentication path, a malicious SSH server could send a USERAUTH_INFO_REQUEST with an attacker-controlled prompt count, and the client would use that raw count directly in Vec::with_capacity(…) before validating that enough prompt data was actually present in the packet. This is a client-side denial-of-service / resource-exhaustion issue on the keyboard-interactive auth path.

Russh: SSH identification parsing accepted non-canonical client banners and did not bound pre-banner input

russh did not enforce the SSH identification-string rules as deliberately as OpenSSH. In particular, the server-side identification reader used the same permissive path as the client, allowing pre-banner lines from clients, and the reader did not enforce a bounded number of pre-banner lines. For a library server built on russh, this could allow a remote peer to hold connection setup resources in the cleartext pre-authentication phase with malformed identification input …

Russh SSH message fields were decoded through allocation-first parsers before field-specific bounds

Several russh client and server message handlers decoded attacker-controlled SSH strings, name-lists, and byte fields into owned allocations before applying field-specific bounds. A remote SSH peer could send oversized, high-fanout, or malformed length-prefixed fields and make the library allocate, attempt to allocate, or split data before rejecting input that should have been rejected earlier.

russh: Post-decompression SSH packet size was not bounded, allowing remote oversized compressed packets

When SSH compression is enabled, russh accepted compressed packets whose on-wire size passed the normal transport packet-length checks but whose decompressed size was much larger. This allowed a remote peer to send oversized post-decompression packets that should have been rejected. In current releases, this is a remote denial-of-service / resource-exhaustion issue in the post-decompression receive path. In older releases before 0.58.0, the same remote decompression path used CryptoVec, which appears …

russh server userauth state is not reset when authentication principal changes

The russh server authentication path keeps internal userauth state across SSH_MSG_USERAUTH_REQUEST messages without separating that state when the request principal changes. RFC 4252 allows the user name and service name fields to change between authentication requests. The issue is not that such changes are invalid. The issue is that russh-owned authentication state, such as remaining methods, partial-success state, and in-progress method state, can remain associated with the connection and then …

Russh: Unchecked CryptoVec allocation and growth handling is reachable

CryptoVec used unchecked capacity growth, unchecked length arithmetic, and unsafe allocation/locking paths. In current russh releases, local SSH agent peers could still feed attacker-controlled frame lengths into buffer growth before validation. In older russh releases before 0.58.0, remote SSH traffic also reached CryptoVec through transport and compression buffers.

2025

russh is missing overflow checks during channel windows adjust

The channel window adjust message of the SSH protocol is used to track the free space in the receive buffer of the other side of a channel. The current implementation takes the value from the message and adds it to an internal state value. This can result in a integer overflow. If the Rust code is compiled with overflow checks, it will panic. A malicious client can crash a server.

2024
2023