Every CVE Search/ Get API key

CVE-2026-68930

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

6.5 MediumFix available

Russh is a Rust SSH client & server library. Prior to 0.62.5, russh dispatches channel-scoped Handler callbacks for recipient channel IDs that were never opened or confirmed in russh/src/server/encrypted.rs, server_read_authenticated, and the exec_request callback. Version 0.62.5 fixes the issue.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
High
Availability
None

Exploit likelihood

0.38%Up 0.2 points since Aug 4, 2026
90%50%10%1%

What each source reports

CVE List Score used 6.5

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

Russh is a Rust SSH client & server library. Prior to 0.62.5, russh dispatches channel-scoped Handler callbacks for recipient channel IDs that were never opened or confirmed in russh/src/server/encrypted.rs, server_read_authenticated, and the exec_request callback. Version 0.62.5 fixes the issue.

Record
CVE-2026-68930
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N
Weakness
CWE-666, CWE-696, CWE-863
Updated
2026-11-02
EUVDEUVD-2026-52337 6.5

Russh is a Rust SSH client & server library. Prior to 0.62.5, russh dispatches channel-scoped Handler callbacks for recipient channel IDs that were never opened or confirmed in russh/src/server/encrypted.rs, server_read_authenticated, and the exec_request callback. Version 0.62.5 fixes the issue.

Record
EUVD-2026-52337
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-m65r-rprj-r5rg 6.5

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

There is a server-side channel state issue in russh.

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

This 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.

Impact

An authenticated client can bypass the server application's channel-open policy.

A server may deny session channels by returning false from Handler::channel_open_session. A server may also assume that callbacks such as exec_request, shell_request, subsystem_request, data, channel_eof, or channel_close are only delivered for channels that were opened and confirmed by the SSH transport layer.

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, exec_request, shell_request, or subsystem_request start commands, jobs, shells, SFTP-like subsystems, internal workflows, or other state-changing operations. In the PoC, the protected exec_request action runs even though no channel was opened.

Why this is not intended behavior

SSH 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 exec request is a SSH_MSG_CHANNEL_REQUEST for a session channel. That means the recipient channel should refer to a channel that exists in the local open-channel state.

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, russh should not deliver session-specific callbacks for that recipient ID.

This is also not just a handler bug. The handler does not own the transport channel table. russh does. The application gets a channel_open_* callback and returns whether the channel is allowed. If that decision is denied, or if the client never requested a channel at all, channel-scoped callbacks should not be reachable.

Documentation and API boundary

The public API documentation supports this boundary.

channel_open_session is the application hook for creating a new session channel, and its boolean return value is the application's decision on whether that channel open should be granted. Separately, exec_request is the application hook for deciding what to do with a command request received on a channel.

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 exec_request for a recipient ChannelId that is absent from the established channel table bypasses the channel-open decision before the application can safely rely on it.

Root cause

In server_read_authenticated in russh/src/server/encrypted.rs, channel-scoped messages are decoded and then dispatched to handler callbacks without a mandatory check that the recipient channel is established in the encrypted session's channel table.

The problematic pattern is visible in the CHANNEL_REQUEST handling. The code reads the recipient channel ID and request fields. It may look up the channel to send an internal ChannelMsg into the stream API, but the handler callback is outside that guard.

For example,…

Record
GHSA-m65r-rprj-r5rg
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N
Weakness
CWE-666, CWE-696, CWE-863
Updated
2026-11-02
NVD 6.5

Russh is a Rust SSH client & server library. Prior to 0.62.5, russh dispatches channel-scoped Handler callbacks for recipient channel IDs that were never opened or confirmed in russh/src/server/encrypted.rs, server_read_authenticated, and the exec_request callback. Version 0.62.5 fixes the issue.

Record
CVE-2026-68930
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N
Weakness
CWE-666, CWE-696, CWE-863
Updated
2026-11-02
OSV 6.5

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

Russh is a Rust SSH client & server library. Prior to 0.62.5, russh dispatches channel-scoped Handler callbacks for recipient channel IDs that were never opened or confirmed in russh/src/server/encrypted.rs, server_read_authenticated, and the exec_request callback. Version 0.62.5 fixes the issue.

Record
CVE-2026-68930
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N
Weakness
CWE-666, CWE-696, CWE-863
Updated
2026-11-02
OSVDEBIAN-CVE-2026-68930 6.5

Russh is a Rust SSH client & server library. Prior to 0.62.5, russh dispatches channel-scoped Handler callbacks for recipient channel IDs that were never opened or confirmed in russh/src/server/encrypted.rs, server_read_authenticated, and the exec_request callback. Version 0.62.5 fixes the issue.

Record
DEBIAN-CVE-2026-68930
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N
Updated
2026-11-02
OSVGHSA-m65r-rprj-r5rg 6.5

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

There is a server-side channel state issue in russh.

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

This 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.

Impact

An authenticated client can bypass the server application's channel-open policy.

A server may deny session channels by returning false from Handler::channel_open_session. A server may also assume that callbacks such as exec_request, shell_request, subsystem_request, data, channel_eof, or channel_close are only delivered for channels that were opened and confirmed by the SSH transport layer.

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, exec_request, shell_request, or subsystem_request start commands, jobs, shells, SFTP-like subsystems, internal workflows, or other state-changing operations. In the PoC, the protected exec_request action runs even though no channel was opened.

Why this is not intended behavior

SSH 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 exec request is a SSH_MSG_CHANNEL_REQUEST for a session channel. That means the recipient channel should refer to a channel that exists in the local open-channel state.

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, russh should not deliver session-specific callbacks for that recipient ID.

This is also not just a handler bug. The handler does not own the transport channel table. russh does. The application gets a channel_open_* callback and returns whether the channel is allowed. If that decision is denied, or if the client never requested a channel at all, channel-scoped callbacks should not be reachable.

Documentation and API boundary

The public API documentation supports this boundary.

channel_open_session is the application hook for creating a new session channel, and its boolean return value is the application's decision on whether that channel open should be granted. Separately, exec_request is the application hook for deciding what to do with a command request received on a channel.

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 exec_request for a recipient ChannelId that is absent from the established channel table bypasses the channel-open decision before the application can safely rely on it.

Root cause

In server_read_authenticated in russh/src/server/encrypted.rs, channel-scoped messages are decoded and then dispatched to handler callbacks without a mandatory check that the recipient channel is established in the encrypted session's channel table.

The problematic pattern is visible in the CHANNEL_REQUEST handling. The code reads the recipient channel ID and request fields. It may look up the channel to send an internal ChannelMsg into the stream API, but the handler callback is outside that guard.

For example,…

Record
GHSA-m65r-rprj-r5rg
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N
Weakness
CWE-666, CWE-696, CWE-863
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
russh
crates.io
through 0.62.4
0.62.5
rust-russh
Debian:14
before 0.64.1-1, plus listed versions
0.57.1-10.57.1-2
0.64.1-1
russh
crates.io
before 0.62.5
0.62.5

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-68930 is a medium vulnerability (CVSS 6.5) in Eugeny Russh, published August 3, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.38%, the 31st percentile. Fixed in russh 0.62.5.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open