Oct 1, 2026·5 min read·8 visits
Authenticated remote peers can trigger unbounded memory growth in russh by starting a rekey, stalling the handshake, and flooding connection-layer packets which accumulate in an undrained heap queue.
An uncontrolled resource consumption vulnerability in the russh library allows remote authenticated attackers to exhaust server memory (heap) by flooding channel open requests during a stalled key re-exchange (rekeying) process, causing a denial of service via Out-of-Memory (OOM) termination.
The russh library is an asynchronous Rust implementation of the SSH2 protocol, built atop the tokio framework. It serves as an underlying engine for SSH clients, servers, port-forwarding proxies, and file transfer systems. Prior to version 0.63.2, the library contains a state-gating flaw in its session-handling layer.
When a key re-exchange (rekeying) is initiated, the connection state transitions to an active negotiation phase. To maintain compliance with SSH protocol specifications, specifically RFC 4253 Section 7.1, the server suspends the outbound processing and polling of connection-layer channels. This suspension is intended to prevent the interleaving of data traffic with cryptographic key exchange packets.
However, while the outbound queue processing is disabled, the incoming socket reader continues to receive and process packets. This mismatch allows an authenticated client to flood connection-layer requests, such as channel open messages. Because the server cannot transmit the responses, it queues them in an unbounded memory buffer, resulting in memory exhaustion.
The root cause lies in the asymmetrical gating of the network event loop during the key re-exchange sequence. In russh/src/server/session.rs, when a rekey begins, the session state transitions to SessionKexState::InProgress(kex). While in this state, the server stops polling the internal priority_receiver channel to ensure protocol order compliance.
Despite the outbound queue being blocked, the main event loop in russh/src/server/mod.rs continues to read and decrypt packets from the active TCP socket. When an authenticated client transmits a channel open message (SSH_MSG_CHANNEL_OPEN), the server processes the payload. It generates a corresponding rejection or acknowledgment packet and pushes it into the priority_sender channel.
Because priority_receiver is an unbounded Multi-Producer Single-Consumer (MPSC) channel, and its draining mechanism is completely suspended, every incoming request causes a new response to accumulate in heap memory. The attacker controls the rate and quantity of these allocations, leading to linear memory growth.
The vulnerability was resolved in commit a282af361ac99bc76b80876d1aae128e89dbf66b by introducing state validation and accounting limits on pending packet sizes during key negotiation. Below is a comparison of the mitigation introduced in the core packet processing function.
// In russh/src/server/mod.rs and russh/src/client/mod.rs
// The patch validates the incoming packet against the KEX state
if !is_kex_msg && session.common.encrypted.is_some() {
if let (Some(&msg_type), SessionKexState::InProgress(kex)) =
(pkt.buffer.first(), &session.kex)
{
if msg_type >= msg::USERAUTH_REQUEST {
// If the peer's KEXINIT was already received, reject non-transport packets
if kex.peer_kexinit_received() {
return Err(crate::Error::Inconsistent.into());
}
// Aggregate the length of the pending messages
session.pending_len =
session.pending_len.saturating_add(pkt.buffer.len() as u32);
// Disconnect if the size exceeds double the window size
if u64::from(session.pending_len)
> 2 * u64::from(session.common.config.window_size)
{
return Err(crate::Error::Pending.into());
}
}
}
}The implementation tracks whether the peer's KEXINIT has been received using peer_kexinit_received(). If it has, any non-transport packet is immediately identified as a protocol violation and rejected. If the peer's packet has not yet arrived (meaning the rekey was initiated by the local host), the incoming packets are buffered, but their cumulative size is strictly limited to twice the configured window_size to prevent unbounded heap allocation.
To execute the denial of service attack, an adversary must possess valid authentication credentials to establish a session with the target SSH server. The exploit sequence proceeds as follows.
First, the client establishes an encrypted session and completes authentication. Second, the client sends an SSH_MSG_KEXINIT packet to trigger a key rekeying process. The server transitions its internal state to InProgress and responds with its own negotiation parameters.
Third, the client deliberately stalls the key exchange by withholding the required key agreement initiation messages (such as SSH_MSG_KEX_ECDH_INIT). Fourth, the client streams a high-frequency sequence of SSH_MSG_CHANNEL_OPEN packets. The server generates response packets for each channel request, storing them indefinitely on the heap. This flow persists until the system kernel terminates the process due to physical or virtual memory exhaustion.
The security impact of CVE-2026-102821 is classified as a high-impact Denial of Service (DoS). The vulnerability allows any authenticated user, regardless of their privilege level, to terminate the SSH server daemon. This affects not only the attacker's session but also all other active sessions and services relying on the russh instance.
The vulnerability is assigned a CVSS v3.1 score of 6.5 (Medium). The base metric reflects network accessibility, low attack complexity, and low required privileges. No user interaction is required, and the impact is confined strictly to availability.
In containerized environments, such as Kubernetes pods or Docker containers, a process crash caused by an Out-of-Memory (OOM) event may trigger container restarts, leading to broader service disruption. In standalone deployments without automatic service supervisors, the service remains offline until manual intervention is performed.
The definitive remediation for this vulnerability is upgrading the russh library dependency to version 0.63.2 or later. This version enforces the RFC-compliant packet-gating and size limit check.
To apply the update, modify the project's dependency manifest and update the cargo lockfile.
# Cargo.toml
[dependencies]
russh = "0.63.2"cargo update -p russhIf upgrading the library is not immediately possible, three network-level and configuration-level mitigations should be implemented. First, apply an inactivity timeout within the russh server configuration to close stagnant handshakes. Second, implement firewall-level rate limiting to restrict the volume of connection-layer packets from a single source. Third, configure system-level resource limits (such as ulimit or systemd memory limits) to isolate the impact of memory exhaustion on co-located services.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
russh Eugeny | >= 0.58.0, < 0.63.2 | 0.63.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-400 |
| Attack Vector | Network (AV:N) |
| CVSS Score | 6.5 (Medium) |
| EPSS Score | 0.00295 |
| Exploit Status | No public functional exploit |
| KEV Status | Not listed in CISA KEV |
| Impact | Denial of Service (Memory Exhaustion / Crash) |
The product does not properly control the allocation and maintenance of a limited resource, enabling an actor to influence the amount of resources consumed.
An authorization bypass and path traversal vulnerability exists in the SiYuan knowledge workspace platform. The vulnerability is located in the '/api/file/getUniqueFilename' endpoint inside the 'github.com/siyuan-note/siyuan/kernel' package. Under default configurations, this route is exposed to users who satisfy basic authentication middleware checks, which includes anonymous readers in publish mode. By supplying unvalidated absolute paths, remote attackers can verify the existence of files and directories across the host operating system, establishing a high-fidelity file existence oracle.
A highly critical Regular Expression Denial of Service (ReDoS) vulnerability in basic-ftp, an FTP client library for Node.js. In versions prior to 6.2.1, a malicious or compromised FTP server can exploit this vulnerability to force the FTP client to consume quadratic CPU time during directory parsing. This issue blocks the single-threaded Node.js event loop, freezing the application process and leading to a complete Denial of Service (DoS).
A critical memory handling vulnerability exists in the pageant crate, a workspace component of the Rust-based russh SSH client library, during communication with the PuTTY Pageant SSH agent on Windows systems. Prior to version 0.2.3, the library's shared memory parsing logic blindly trusted a peer-controlled, 32-bit big-endian response length field. This allows local attackers running within the same user session to trigger out-of-bounds reads or execute an out-of-memory crash of the client application.
A validation bypass vulnerability exists in Fastify web framework prior to version 5.12.2. The flaw stems from shallow normalization of header validation schemas, which fails to lowercase nested or conditional schema rules (like JSON Schema dependencies or dependentRequired) defined in mixed or canonical casing. Consequently, because Node.js normalizes incoming HTTP request headers to lowercase, the compiled validator fails to match these headers against the un-normalized mixed-case schema triggers, silently skipping conditional checks and allowing unauthenticated attackers to bypass authorization or security headers.
CVE-2026-84469 is a high-severity request validation bypass vulnerability in the Fastify Node.js web framework. In versions prior to 5.12.2, Fastify uses loose truthiness checks to decide whether to compile request schemas. When a component (such as the body) is explicitly configured with a boolean 'false' schema—which under JSON Schema Draft 7 acts as a 'deny-all' constraint—Fastify's internal logic evaluates this as a falsy value and skips compilation entirely. This allows unauthenticated remote attackers to send arbitrary payloads to these endpoints, bypassing validation checks and directly executing backend route handlers.
An authentication bypass vulnerability in the Fastify web framework allows remote attackers to access private custom not-found handlers by submitting requests with malformed URLs. This bypasses the typical request lifecycle and its associated authorization hooks.