CVE-2026-46702
Russh: Post-decompression SSH packet size was not bounded, allowing remote oversized compressed packets
Russh is a Rust SSH client & server library. From version 0.34.0 to before version 0.61.1, when SSH compression is enabled, russh accepted compressed packets whose on-wire size passed the normal transport packet-length checks but whose decompressed size was much larger. This allowed a remote peer to send oversized post-decompression packets that should have been rejected. In current releases, this is a remote denial-of-service / resource-exhaustion issue in the post-decompression receive path. In older releases before 0.58.0, the same remote decompression path used CryptoVec, which appears to make the historical impact worse. This issue has been patched in version 0.61.1.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
7.5
Russh: Post-decompression SSH packet size was not bounded, allowing remote oversized compressed packets
Russh is a Rust SSH client & server library. From version 0.34.0 to before version 0.61.1, when SSH compression is enabled, russh accepted compressed packets whose on-wire size passed the normal transport packet-length checks but whose decompressed size was much larger. This allowed a remote peer to send oversized post-decompression packets that should have been rejected. In current releases, this is a remote denial-of-service / resource-exhaustion issue in the post-decompression receive path. In older releases before 0.58.0, the same remote decompression path used CryptoVec, which appears to make the historical impact worse. This issue has been patched in version 0.61.1.
- Record
CVE-2026-46702- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-770
- Updated
- 2026-11-02
EUVDEUVD-2026-36125
7.5
Russh is a Rust SSH client & server library. From version 0.34.0 to before version 0.61.1, when SSH compression is enabled, russh accepted compressed packets whose on-wire size passed the normal transport packet-length checks but whose decompressed size was much larger. This allowed a remote peer to send oversized post-decompression packets that should have been rejected. In current releases, this is a remote denial-of-service / resource-exhaustion issue in the post-decompression receive path. In older releases before 0.58.0, the same remote decompression path used CryptoVec, which appears to make the historical impact worse. This issue has been patched in version 0.61.1.
- Record
EUVD-2026-36125- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-wwx6-x28x-8259
7.5
russh: Post-decompression SSH packet size was not bounded, allowing remote oversized compressed packets
Summary
When SSH compression is enabled, russh accepted compressed packets whose on-wire size passed the normal transport packet-length checks but whose decompressed size was much larger. This allowed a remote peer to send oversized post-decompression packets that should have been rejected.
In current releases, this is a remote denial-of-service / resource-exhaustion issue in the post-decompression receive path.
In older releases before 0.58.0, the same remote decompression path used CryptoVec, which appears to make the historical impact worse.
Details
The normal SSH transport read path enforces a packet-length limit before the packet body is read:
russh/src/cipher/mod.rs
However, RFC 4253 compression is applied to the SSH payload field only. The packet_length field and MAC are computed over the compressed payload, so a packet that is reasonably sized on the wire can still expand to a much larger message body after decompression.
In russh, compressed packet bodies are later decompressed in:
russh/src/compression.rsrussh/src/client/mod.rsrussh/src/server/session.rs
Before the fix, Decompress::decompress() grew its output buffer by repeated doubling and did not enforce a separate post-decompression ceiling. That meant a peer could send a small compressed packet that passed the normal on-wire transport length checks and then inflate it into a much larger packet after decompression.
It was verified that an attacker-crafted compressed payload can stay below the normal 256 KiB implementation transport packet cap while still inflating above the intended post-decompression bound. In other words, this is not only a "large on-wire packet" issue.
Version detail:
- The underlying post-decompression bounds bug appears to affect
russhas far back as0.34.0. - In historical releases
>= 0.34.0, < 0.58.0, the remote decompression path still usedCryptoVec. Remote compressed SSH traffic could drive that path, and under constrained memory that historical code path could abort the process. - In current-style releases
>= 0.58.0, non-secret packet/decompression buffers were moved offCryptoVecand ontoVec<u8>, but the post-decompression size still remained unbounded. So the bug class remained reachable remotely, but the maintained-line impact is a current remote DoS / oversized-packet-acceptance issue rather than the olderCryptoVec-based abort story. - The maintained-line fix was verified against
0.60.2.
Compression is not selected in a default-vs-default russh session because the default preference order puts none first. However, the default server configuration still advertises zlib and [email protected], and server-side negotiation follows the client's preference order for common algorithms. A client that prefers compression can therefore negotiate it with a default russh server.
OpenSSH portable was checked at /home/mjc/projects/openssh-portable commit 45b30e0a5. OpenSSH enforces a 256 KiB transport packet cap before decompression, but it does not reuse that cap after decompression. Instead, decompression writes to an sshbuf, which is indirectly bounded by OpenSSH's SSHBUF_SIZE_MAX hard maximum of 0x8000000 bytes (128 MiB).
The patch direction should follow that model: add an explicit post-decompression ceiling of 128 MiB, rather than assuming the compressed transport packet cap also bounds decompressed payload size.
Relevant OpenSSH reference points:
/home/mjc/projects/openssh-portable/packet.c:PACKET_MAX_SIZE (256 * 1024)/home/mjc/projects/openssh-portable/packet.c:uncompress_buffer()inflates intocompression_buffer/home/mjc/projects/openssh-portable/sshbuf.h:SSHBUF_SIZE_MAX 0x8000000
RFC / OpenSSH Comparison
RFC 4253 section 6 defines the binary packet format:
packet_lengthpadding_lengthpayload- random padding
- MAC
RFC 4253 section 6.2 says that, when compression is negotiated, the…
- Record
GHSA-wwx6-x28x-8259- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-770
- Updated
- 2026-11-02
NVD
7.5
Russh is a Rust SSH client & server library. From version 0.34.0 to before version 0.61.1, when SSH compression is enabled, russh accepted compressed packets whose on-wire size passed the normal transport packet-length checks but whose decompressed size was much larger. This allowed a remote peer to send oversized post-decompression packets that should have been rejected. In current releases, this is a remote denial-of-service / resource-exhaustion issue in the post-decompression receive path. In older releases before 0.58.0, the same remote decompression path used CryptoVec, which appears to make the historical impact worse. This issue has been patched in version 0.61.1.
- Record
CVE-2026-46702- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-770
- Updated
- 2026-11-02
OSV
7.5
Russh: Post-decompression SSH packet size was not bounded, allowing remote oversized compressed packets
Russh is a Rust SSH client & server library. From version 0.34.0 to before version 0.61.1, when SSH compression is enabled, russh accepted compressed packets whose on-wire size passed the normal transport packet-length checks but whose decompressed size was much larger. This allowed a remote peer to send oversized post-decompression packets that should have been rejected. In current releases, this is a remote denial-of-service / resource-exhaustion issue in the post-decompression receive path. In older releases before 0.58.0, the same remote decompression path used CryptoVec, which appears to make the historical impact worse. This issue has been patched in version 0.61.1.
- Record
CVE-2026-46702- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-770
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-46702
7.5
Russh is a Rust SSH client & server library. From version 0.34.0 to before version 0.61.1, when SSH compression is enabled, russh accepted compressed packets whose on-wire size passed the normal transport packet-length checks but whose decompressed size was much larger. This allowed a remote peer to send oversized post-decompression packets that should have been rejected. In current releases, this is a remote denial-of-service / resource-exhaustion issue in the post-decompression receive path. In older releases before 0.58.0, the same remote decompression path used CryptoVec, which appears to make the historical impact worse. This issue has been patched in version 0.61.1.
- Record
DEBIAN-CVE-2026-46702- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
OSVGHSA-wwx6-x28x-8259
7.5
russh: Post-decompression SSH packet size was not bounded, allowing remote oversized compressed packets
Summary
When SSH compression is enabled, russh accepted compressed packets whose on-wire size passed the normal transport packet-length checks but whose decompressed size was much larger. This allowed a remote peer to send oversized post-decompression packets that should have been rejected.
In current releases, this is a remote denial-of-service / resource-exhaustion issue in the post-decompression receive path.
In older releases before 0.58.0, the same remote decompression path used CryptoVec, which appears to make the historical impact worse.
Details
The normal SSH transport read path enforces a packet-length limit before the packet body is read:
russh/src/cipher/mod.rs
However, RFC 4253 compression is applied to the SSH payload field only. The packet_length field and MAC are computed over the compressed payload, so a packet that is reasonably sized on the wire can still expand to a much larger message body after decompression.
In russh, compressed packet bodies are later decompressed in:
russh/src/compression.rsrussh/src/client/mod.rsrussh/src/server/session.rs
Before the fix, Decompress::decompress() grew its output buffer by repeated doubling and did not enforce a separate post-decompression ceiling. That meant a peer could send a small compressed packet that passed the normal on-wire transport length checks and then inflate it into a much larger packet after decompression.
It was verified that an attacker-crafted compressed payload can stay below the normal 256 KiB implementation transport packet cap while still inflating above the intended post-decompression bound. In other words, this is not only a "large on-wire packet" issue.
Version detail:
- The underlying post-decompression bounds bug appears to affect
russhas far back as0.34.0. - In historical releases
>= 0.34.0, < 0.58.0, the remote decompression path still usedCryptoVec. Remote compressed SSH traffic could drive that path, and under constrained memory that historical code path could abort the process. - In current-style releases
>= 0.58.0, non-secret packet/decompression buffers were moved offCryptoVecand ontoVec<u8>, but the post-decompression size still remained unbounded. So the bug class remained reachable remotely, but the maintained-line impact is a current remote DoS / oversized-packet-acceptance issue rather than the olderCryptoVec-based abort story. - The maintained-line fix was verified against
0.60.2.
Compression is not selected in a default-vs-default russh session because the default preference order puts none first. However, the default server configuration still advertises zlib and [email protected], and server-side negotiation follows the client's preference order for common algorithms. A client that prefers compression can therefore negotiate it with a default russh server.
OpenSSH portable was checked at /home/mjc/projects/openssh-portable commit 45b30e0a5. OpenSSH enforces a 256 KiB transport packet cap before decompression, but it does not reuse that cap after decompression. Instead, decompression writes to an sshbuf, which is indirectly bounded by OpenSSH's SSHBUF_SIZE_MAX hard maximum of 0x8000000 bytes (128 MiB).
The patch direction should follow that model: add an explicit post-decompression ceiling of 128 MiB, rather than assuming the compressed transport packet cap also bounds decompressed payload size.
Relevant OpenSSH reference points:
/home/mjc/projects/openssh-portable/packet.c:PACKET_MAX_SIZE (256 * 1024)/home/mjc/projects/openssh-portable/packet.c:uncompress_buffer()inflates intocompression_buffer/home/mjc/projects/openssh-portable/sshbuf.h:SSHBUF_SIZE_MAX 0x8000000
RFC / OpenSSH Comparison
RFC 4253 section 6 defines the binary packet format:
packet_lengthpadding_lengthpayload- random padding
- MAC
RFC 4253 section 6.2 says that, when compression is negotiated, the…
- Record
GHSA-wwx6-x28x-8259- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-770
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
russhcrates.io |
0.34.0 up to 0.61.1 | 0.61.1 |
rust-russhDebian:14 |
before 0.64.1-1, plus listed versions 0.57.1-10.57.1-2 |
0.64.1-1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-46702 is a high vulnerability (CVSS 7.5) in Eugeny Russh, published May 29, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.27%, the 19th percentile. Fixed in russh 0.61.1.
References
Left out here: the rest of 2 source descriptions. The JSON record has them.