russh
Rust SSH client & server library
Activity
- Latest release
- 3d ago
- Total releases
- 133
- Cadence
- ~8 days
- Last 12 months
- 30
Reach
- Downloads
- 9.0M
- Stars
- 1.9k
Details
- License
- Apache-2.0
- First release
- Mar 13, 2022
| Version | Released | |
|---|---|---|
0.65.0
minor
|
0.65.0
minor
Dependencies (78)
+ 70 more
Changelog
Compare changes
|
|
0.64.1
patch
|
0.64.1
patch
Dependencies (79)
+ 71 more
Changelog
Compare changes
|
|
0.64.0
minor
1 CVE
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev |
0.64.0
minor
Dependencies (79)
+ 71 more
Changelog
Compare changes
|
|
0.63.3
patch
2 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev |
0.63.3
patch
Dependencies (80)
+ 72 more
Changelog
Compare changes
|
|
0.63.2
patch
2 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev |
0.63.2
patch
Dependencies (80)
+ 72 more
Changelog
Compare changes
|
|
0.63.1
patch
3 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev |
0.63.1
patch
Dependencies (81)
+ 73 more
Changelog
Compare changes
|
|
0.63.0
minor
5 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev |
0.63.0
minor
Dependencies (81)
+ 73 more
Changelog
Compare changes
|
|
0.63.0-beta.1
pre
6 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev |
0.63.0-beta.1
pre
Dependencies (81)
+ 73 more
Changelog
Compare changes
|
|
0.62.7
patch
6 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev |
0.62.7
patch
Dependencies (81)
+ 73 more
Changelog
Compare changes
|
|
0.62.6
patch
6 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev |
0.62.6
patch
Dependencies (81)
+ 73 more
Changelog
Compare changes
|
|
0.62.5
patch
7 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev |
0.62.5
patch
Dependencies (81)
+ 73 more
Changelog
Compare changes
|
|
0.62.4
patch
8 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev |
0.62.4
patch
Dependencies (81)
+ 73 more
Changelog
Compare changes
|
|
0.62.3
patch
11 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.62.3
patch
Dependencies (81)
+ 73 more
Changelog
Compare changes
|
|
0.62.2
patch
11 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.62.2
patch
Dependencies (81)
+ 73 more
Changelog
Compare changes
|
|
0.62.1
patch
11 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.62.1
patch
Dependencies (81)
+ 73 more
Changelog
Compare changes
|
|
0.62.0
minor
11 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.62.0
minor
Dependencies (81)
+ 73 more
Changelog
Compare changes
|
|
0.61.2
patch
11 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.61.2
patch
Dependencies (81)
+ 73 more
Changelog
Compare changes
|
|
0.61.1
patch
11 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.61.1
patch
Dependencies (82)
+ 74 more
Changelog
Compare changes
|
|
0.61.0
minor
12 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.61.0
minor
Dependencies (82)
+ 74 more
Changelog
Compare changes
|
|
0.60.3
patch
16 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.60.3
patch
Dependencies (84)
+ 76 more
Changelog
Compare changes
|
|
0.60.2
patch
17 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.60.2
patch
Dependencies (84)
+ 76 more
Changelog
Compare changes
|
|
0.60.1
patch
17 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.60.1
patch
Dependencies (75)
+ 67 more
Changelog
Compare changes
|
|
0.60.0
minor
18 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.60.0
minor
Dependencies (75)
+ 67 more
Changelog
Compare changes
|
|
0.59.0
minor
18 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.59.0
minor
Dependencies (70)
+ 62 more
Changelog
Compare changes
|
|
0.58.1
patch
yanked
18 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.58.1
patch
yanked
Dependencies (70)
+ 62 more
Changelog
Compare changes
|
|
0.58.0
minor
18 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.58.0
minor
Dependencies (70)
+ 62 more
Changelog
Compare changes
|
|
0.57.1
patch
18 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.57.1
patch
Dependencies (71)
+ 63 more
Changelog
Compare changes
|
|
0.57.0
minor
18 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.57.0
minor
Dependencies (71)
+ 63 more
Changelog
Compare changes
|
|
0.56.0
minor
18 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.56.0
minor
Dependencies (71)
+ 63 more
Changelog
Compare changes
|
|
0.55.0
minor
18 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.55.0
minor
Dependencies (71)
+ 63 more
Changelog
Compare changes
|
|
0.54.6
patch
18 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.54.6
patch
Dependencies (73)
+ 65 more
Changelog
Compare changes
|
|
0.54.5
patch
18 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.54.5
patch
Dependencies (72)
+ 64 more
Changelog
Compare changes
|
|
0.54.4
patch
18 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.54.4
patch
Dependencies (72)
+ 64 more
Changelog
Compare changes
|
|
0.54.3
patch
18 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.54.3
patch
Dependencies (72)
+ 64 more
Changelog
Compare changes
|
|
0.54.2
patch
18 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.54.2
patch
Dependencies (72)
+ 64 more
Changelog
Compare changes
|
|
0.54.1
patch
18 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.54.1
patch
Dependencies (72)
+ 64 more
Changelog
Compare changes
|
|
0.54.0
minor
19 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.54.0
minor
Dependencies (72)
+ 64 more
Changelog
Compare changes
|
|
0.53.0
minor
19 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.53.0
minor
Dependencies (72)
+ 64 more
Changelog
Compare changes
|
|
0.53.0-beta.1
pre
19 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.53.0-beta.1
pre
Dependencies (72)
+ 64 more
Changelog
Compare changes
|
|
0.52.1
patch
19 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.52.1
patch
Dependencies (71)
+ 63 more
Changelog
Compare changes
|
|
0.52.0
minor
19 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.52.0
minor
Dependencies (71)
+ 63 more
Changelog
Compare changes
|
|
0.52.0-beta.1
pre
19 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.52.0-beta.1
pre
Dependencies (71)
+ 63 more
Changelog
Compare changes
|
|
0.51.1
patch
19 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.51.1
patch
Dependencies (71)
+ 63 more
Changelog
Compare changes
|
|
0.51.0
minor
19 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.51.0
minor
Dependencies (71)
+ 63 more
Changelog
Compare changes
|
|
0.51.0-beta.3
pre
19 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.51.0-beta.3
pre
Dependencies (71)
+ 63 more
Changelog
Compare changes
|
|
0.51.0-beta.2
pre
19 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.51.0-beta.2
pre
Dependencies (71)
+ 63 more
Changelog
Compare changes
|
|
0.51.0-beta.1
pre
19 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.51.0-beta.1
pre
Dependencies (71)
+ 63 more
Changelog
Compare changes
|
|
0.50.4
patch
19 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.50.4
patch
Dependencies (71)
+ 63 more
Changelog
Compare changes
|
|
0.50.3
patch
19 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.50.3
patch
Dependencies (71)
+ 63 more
Changelog
Compare changes
|
|
0.50.2
patch
19 CVEs
CVE-2026-111061
GHSA-4wc5-f2rc-q74m
Oct 19, 2026
russh: Unbounded memory allocation in agent protocol server via crafted constraint records
4.3
/ 10
Medium
Adjacent
Low
None
None
Unchanged
None
None
Low
Summary
Details
Each lifetime record clones the key blob into a new task regardless of how many records the same request already spawned, and a failure later in the request leaves earlier tasks alive. Data flow: agent connection -> SSH_AGENTC_ADD_IDENTITY_CONSTRAINED -> constraint decode loop -> unbounded Proof of conceptPrerequisites: Linux host with cargo and git. The archive's deploy script provisions russh at the pinned revision and the PoC crate (rewriting the path dependency); the PoC runs a real russh agent server on loopback and speaks the agent protocol to it.
The broker acks every request (code 6 = SUCCESS) while RSS grows to +1.45 GB from ~10 MiB of input. The harness's control mode (same wire volume, unconstrained adds) measured +268 KiB. The automated archive run reproduces exactly this trace. Manual reproduction, step by step (no archive required)
ImpactAn attacker able to speak the agent protocol to a russh-based agent (local process on the socket, or a remote SSH server the user connects to with agent forwarding enabled) can drive gigabyte-scale memory growth and millions of leaked tasks per session with megabytes of traffic, renewable until the agent process is starved or OOM-killed, taking the user's SSH key agent down. The trust boundary is the agent protocol peer versus the agent process's resources. No confidentiality or integrity impact. Fixed in
0.64.1
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-111062
GHSA-j7h2-66j4-ghjf
Oct 19, 2026
A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request
Low
Network
High
Low
None
DetailsIn
So for an RSA key, the request can say Affected versions: every russh release, from the first ( The mechanism changed over time, but the outcome is the same: the hash is always taken from the signature blob, never checked against the request.
Confirmed by running the PoC below on 0.63.3. Confirmed by reading the code of PoCA unit test in the existing test module of
Result on unmodified 0.63.3:
With the fix below, the test passes and the whole library suite still passes: Suggested fix: reject a mismatch through the existing
ImpactThis is a missing check on the signature algorithm (improper verification of a cryptographic signature's algorithm, CWE-347) in the server's Who is impacted: applications that use russh as an SSH server and rely on the requested algorithm to restrict, record or audit user-key signature algorithms. For example:
Such a server can be made to accept a SHA-1 signature, or to record Not impacted:
Fixed in
0.64.0
References Updated Oct 19, 2026 · Source: OSV.dev
CVE-2026-102821
GHSA-35g8-35p8-c8fw
Sep 30, 2026
Russh: Unbounded memory exhaustion via CHANNEL_OPEN flood during a client-stalled rekey
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
High
SummaryA russh server can be driven to unbounded heap growth (process OOM / kill) by a peer that speaks only standard SSH messages, in the default configuration. The peer starts a key re-exchange (sends This is reproducible end-to-end against a real russh server over a real encrypted transport; see "Proof of concept". A one-line negative control (same flood, no rekey) keeps memory flat, isolating the rekey window as the sole trigger. Impact
Affected component
Verified on v0.63.1 (commit Details
The fourth arm, During a rekey, Whether the handler accepts or (the trait default) rejects, the handle's
Two facts make this unbounded and remote:
Root causeThe intended design was to buffer packets received during a rekey and replay
them afterwards: the fields Proof of conceptEverything runs inside a container; nothing touches the host. Lab.
A minimal server (
The control isolates the rekey window as the sole trigger. Both legs exercise
the real server entry point ( Reproduce: RemediationThe priority queue carries locally generated channel-open replies, which are non-kex messages the server must not send during a rekey anyway (RFC 4253 §7.1). So the fix is to bound how much channel work is done during a rekey, not to drain the queue mid-rekey. Any of:
OpenSSH does not service new channels mid-kex; matching that intent closes the whole family. Fixed in
0.63.2
References Updated Oct 01, 2026 · Source: OSV.dev
CVE-2026-102822
GHSA-p8qx-h547-fjw9
Sep 30, 2026
russh: negotiating a MAC-requiring block cipher (CTR/CBC) with mac=none causes a slice-index-out-of-range panic
3.7
/ 10
Low
Network
High
None
None
Unchanged
None
None
Low
Summary
DetailsIn
When the negotiated MAC is The file already defines a Negotiation gap: PoC
ImpactDenial of service: a remote peer that can influence MAC preference negotiation (or a MITM in possession of the session key) can crash any individual SSH connection/session that ends up negotiating a block cipher together with Suggested fixIn the MAC-selection logic in For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102823
GHSA-47hw-gvq5-r2gm
Sep 30, 2026
russh: Client-side channel-scoped Handler callbacks fire for channel IDs the client never opened
7.5
/ 10
High
Network
Low
None
None
Unchanged
None
High
None
SummaryCVE-2026-68930 was fixed by adding DetailsIn Corroborating evidence this check was intended but never wired up: Because PoCMany real-world consumers of russh-as-a-client (deployment/orchestration tools, CI runners connecting to build/bastion hosts, git-over-ssh style tooling, database/tunnel clients) implement the A malicious, MITM'd (via a compromised/rogue jump host the client is configured to trust), or simply hostile SSH server can send Impact(1) A reliable, purely protocol-level trigger for an application panic/DoS in any client that indexes per-channel state by Suggested fix: add the same For credit/changelog purposes, please use: Yazan Balawneh, Cystack.ps Fixed in
0.63.1
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102824
GHSA-w3jg-pjxf-73p4
Sep 30, 2026
Russh: Missing X25519 zero-point validation in hybrid ML-KEM key exchange
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
Low
None
None
VulnerabilityThe hybrid ML-KEM 768 + X25519 key exchange implementation in Affected code at HEAD (v0.62.4, commit 0089c89): Server-side (
Client-side (
Root CauseCommit a7fc1eb (2026-07-22, "fix mpint encoding and validate curve25519 keys") added zero-point validation to the standalone Curve25519 KEX in
The same X25519 scalar multiplication pattern appears in Proof of ConceptA malicious SSH client negotiating When the server computes The zero X25519 public key passes all existing validation (the length check on line 78 succeeds since 32 bytes is correct). No panic or crash occurs - the exchange completes successfully with a weakened shared secret. ImpactThe purpose of hybrid key exchange is defense-in-depth: if either the classical algorithm (X25519) or the post-quantum algorithm (ML-KEM 768) is broken, the combined secret remains secure. By injecting a zero X25519 public key, an attacker eliminates the classical contribution entirely, reducing security to depend solely on ML-KEM. This matters in two scenarios:
The severity is MEDIUM rather than HIGH because the ML-KEM component still provides strong security today, and an active attacker who can modify KEX messages can already perform other attacks unless strict KEX is negotiated. Suggested FixAdd zero-point checks in
Ideally, also validate against the other small-subgroup points on Curve25519 (there are a small number of low-order points that also yield a zero shared secret), matching the comprehensive validation OpenSSH performs. AI toolingAI assistancewas used for the code audit and for drafting this report. The finding was manually verified against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own. Fixed in
0.63.0
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-102825
GHSA-g6xm-f9xp-qq35
Sep 30, 2026
Russh: Configured server auth-attempt cap is not enforced in the USERAUTH_REQUEST runtime path
3.7
/ 10
Low
Network
High
None
None
Unchanged
Low
None
None
DetailsAffected versions and vulnerable location
Reachability trace verified
PoCReproduction steps and observed outputI did not run a full server process in this environment because Rust tooling is unavailable. I verified the issue from source and command output on the audited tree.
Observed:
Observed:
Observed:
Observed:
ImpactAttacker model
Suggested fixEnforce Concrete patch direction in
How it was found and a note on toolingThe researcher synthesized three lens outputs, then revalidated each claim against current AI assistance was used while investigating this and while drafting this report. The finding was verified by reading the cited code at HEAD. The vulnerability was not executed it, and that limit is stated plainly above rather than left implied. Credits: arpitjain099. Fixed in
0.62.6
References Updated Sep 30, 2026 · Source: OSV.dev
CVE-2026-68930
GHSA-m65r-rprj-r5rg
Aug 03, 2026
Russh: Channel-scoped server callbacks can be reached without an open channel
6.5
/ 10
Medium
Network
Low
Low
None
Unchanged
None
High
None
There is a server-side channel state issue in After a client is authenticated, This is not an authentication bypass. A valid login is required. The issue is that the SSH channel lifecycle is not enforced before channel-scoped callbacks are delivered to the application. ImpactAn authenticated client can bypass the server application's channel-open policy. A server may deny session channels by returning That assumption does not hold in the vulnerable path. A malicious authenticated peer can send channel-scoped messages for arbitrary recipient channel IDs and cause handler callbacks to run even though no channel exists. The exact impact depends on the downstream application. For many SSH server use cases, Why this is not intended behaviorSSH channel requests are not global post-authentication requests. They are operations on an existing channel. RFC 4254 describes channel-specific messages as carrying a recipient channel number. The The relevant boundary is therefore not password authentication. The boundary is the channel-open decision. If no channel has been opened, or if the application denied the open request, This is also not just a handler bug. The handler does not own the transport channel table. Documentation and API boundaryThe public API documentation supports this boundary.
Those are different responsibilities. The application can decide whether a command is allowed. The library must first decide whether the recipient channel exists and was actually opened. Delivering Root causeIn The problematic pattern is visible in the For example, the
If The same issue applies to other channel-scoped callbacks such as There is a second related problem in The authoritative source for whether a channel is established should be Evidence from the PoCThe PoC uses a real POC Code :
The crafted packet form is:
The PoC runs normal controls and exploit cases in one execution. Allowed controlThis proves the protected action works normally when a session channel is opened.
Denied controlThis proves the application policy denies session channels and a normal client cannot reach the protected action.
Main exploit: no channel openThis is the main issue. The authenticated client does not send
This removes the "guessed channel ID" concern. Every scanned recipient ID reached the protected action in the vulnerable run. Additional variant: denied openThe client asks for a session channel, the handler denies it, and the client then sends the same crafted requests.
The denied-open variant is not required for exploitability, but it shows the same state validation gap after an explicit application denial. Affected code pathVerified at:
The affected logic is in:
The vulnerable area is:
Channel request dispatch decodes a recipient channel ID and calls request-specific handler callbacks without first requiring that the recipient ID exists as a confirmed channel in The affected request callbacks include:
The same missing established-channel guard affects:
A related issue exists in:
Application channel references should not be retained for denied opens. Why this belongs in russhThe application cannot reliably enforce the SSH transport channel lifecycle from inside individual callbacks. By the time This is the same kind of invariant The safe expectation is simple:
Suggested fixBefore dispatching any channel-scoped callback, require the recipient The authoritative check should use A minimal approach is to add a helper like:
Then call it before dispatching channel-scoped callbacks for:
For unknown or unconfirmed channels, The channel-open path should also retain application-side channel references only when the open is approved:
Regression coverageA regression test should authenticate normally, then verify that callbacks are not reached in these cases:
The test should fail if any channel-scoped callback such as A positive control should confirm that a normally opened session channel still reaches the expected callbacks. In the local validation, the targeted regression passed after the patch:
The full workspace also passed:
Duplicate checkI checked existing
Existing advisories cover unrelated authentication, parser, allocation, window-adjust, Terrapin, and cryptographic issues. I did not find an existing advisory or issue for channel-scoped callbacks being dispatched for unopened or denied recipient channel IDs. Fixed in
0.62.5
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73429
GHSA-g9hv-x236-4qp3
Jul 24, 2026
Russh: client wrong-length X25519 `clone_from_slice` panic (pre-auth DoS)
5.3
/ 10
Medium
Network
Low
None
None
Unchanged
None
None
Low
SummaryA malicious SSH server can crash a DetailsEvery other kex path in
Only the client-side curve25519 Incriminated source code (repo-relative paths):
PoCA standalone, self-contained Cargo PoC is provided in
Build & run:
Expected output (verdict line, from a successful reproduction):
The malicious payload is the
The length prefix of ImpactWhat kind of vulnerability: CWE-704 (incorrect type conversion / cast —
Who is impacted: any deployment that uses Workaround: until a fix is released, clients can reduce exposure by
disabling Suggested fix (one-line length check, mirrors the existing server-side
This makes the client-side Fixed in
0.62.4
References Updated Sep 10, 2026 · Source: OSV.dev
CVE-2026-73489
GHSA-cqjc-rmpq-xprq
Jul 24, 2026
Russh: Post-auth remote panic via pty-req with more than 130 terminal-mode records
4.3
/ 10
Medium
Network
Low
Low
None
Unchanged
None
None
Low
SummaryA post-authentication denial-of-service panic in This is reachable with the default server configuration and the default
crypto config (curve25519-sha256 + chacha20-poly1305), requiring only an
authenticated session channel — no caller-supplied parameter. It is reproduced
end-to-end against the unmodified real russh 0.62.2 library (a real
Rust bounds-checked panics abort the task safely (no memory corruption / RCE); the impact is remote denial of service. Details
Each terminal-mode record is exactly 5 bytes (1-byte opcode + 4-byte value),
and
writes every record with no count cap, so 131 records reach the server as a legitimate authenticated channel request. PoCThe PoC is a standalone One-line reproducer
|
0.50.2
patch
Dependencies (71)
+ 63 more
Changelog
Compare changes
|