fix(deps): update rust crate russh to 0.60 [security]#937
Open
renovate[bot] wants to merge 1 commit into
Open
Conversation
94a6f59 to
4535f34
Compare
4535f34 to
9d56e71
Compare
9d56e71 to
604622d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
0.57→0.60Warning
Some dependencies could not be looked up. Check the Dependency Dashboard for more information.
russh has pre-auth DoS via unbounded allocation in its keyboard-interactive auth handler
CVE-2026-42189 / GHSA-f5v4-2wr6-hqmg
More information
Details
Summary
A pre-authentication denial-of-service vulnerability exists in the server's keyboard-interactive authentication handler. A malicious client can crash any russh-based server that implements keyboard-interactive auth (e.g., for 2FA/TOTP) with a single malformed packet, requiring no credentials.
Vulnerability Details
In
russh/src/server/encrypted.rs, the functionread_userauth_info_responsedecodes au32count from the client'sSSH_MSG_USERAUTH_INFO_RESPONSEand passes it directly toVec::with_capacity():An attacker can send
n = 0x10000000(268M) or larger in a minimal packet (~50 bytes after encryption). The server attempts to allocaten * ~24 bytes(size ofOption<Bytes>) = ~6.4GB, causing an OOM crash.Attack Flow
USERAUTH_REQUESTwith methodkeyboard-interactiveAuth::Partialwith prompts (standard for 2FA/TOTP)USERAUTH_INFO_RESPONSEwithn = 0x10000000and no response dataVec::with_capacity(268_435_456), OOM killedNo authentication is required. The allocation occurs before the handler validates any credentials. The attack is repeatable faster than the server can restart.
Affected Configurations
Any russh-based server where the
Handler::auth_keyboard_interactiveimplementation returnsAuth::Partial(i.e., sends prompts to the client). The default handler returnsAuth::reject()and is not affected.Source code review suggests that downstream projects using keyboard-interactive for multi-step auth (e.g., TOTP/2FA) follow the affected pattern, since returning
Auth::Partialbefore credential verification is the intended API usage for prompting.Confirmed End-to-End PoC
There is a complete Docker-contained PoC confirming the OOM kill:
Auth::Partialfor keyboard-interactiveUSERAUTH_INFO_RESPONSEAvailable on request.
Proposed Fix
Cap the
Vec::with_capacityallocation to what the remaining packet data can actually contain. Each response requires at least 4 bytes (length prefix), so:This bounds the allocation to at most the packet size (~256KB), while preserving the existing behavior for well-formed packets. This fix has been implemented, tested, and contributed via the temporary private fork.
Severity
Pre-auth, remote, no credentials required, crashes the server process affecting all active sessions.
Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:HReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Russh: Unchecked CryptoVec allocation and growth handling is reachable
CVE-2026-46673 / GHSA-g9f8-wqj9-fjw5
More information
Details
Title
Unchecked
CryptoVecallocation and growth handling was reachable from local agent inputs in currentrusshreleases and from remote SSH traffic in historical pre-0.58.0releasesSummary
CryptoVecused unchecked capacity growth, unchecked length arithmetic, and unsafe allocation/locking paths. In currentrusshreleases, local SSH agent peers could still feed attacker-controlled frame lengths into buffer growth before validation. In olderrusshreleases before0.58.0, remote SSH traffic also reachedCryptoVecthrough transport and compression buffers.Details
The underlying unsafe paths were in
CryptoVec:cryptovec/src/cryptovec.rscryptovec/src/platform/unix.rsmlock/munlockpreviously accepted zero-length calls and performed null-pointer validation inside theunsafeOS-call pathThere are two relevant reachability stories:
russhrussh/src/keys/agent/client.rsAgentClient::read_response()read a peer-suppliedu32length and then resizedself.bufto that value before reading the payloadrussh/src/keys/agent/server.rsConnection::run()read a peer-suppliedu32length and then resizedself.bufto that value before reading the payloadThis is the path that still existed in current
0.60.xreleases before the fix, although by then those buffers were no longerCryptoVec.russh712e32b(first released inv0.58.0), non-secret transport and compression buffers inrusshstill usedCryptoVec712e32bworktree by adding and running:cipher::tests::remote_packet_length_grows_transport_cryptovec_buffercompression::tests::remote_compressed_payload_expands_cryptovec_outputCryptoVecthrough:Also added a constrained-memory reproduction in that historical worktree:
compression::tests::remote_compressed_payload_can_crash_under_memory_limitThat test re-execs the test binary under
prlimit --as=134217728, decompresses a highly compressible payload that expands to96 MiB, and reliably aborts in the old UnixCryptoVecpath whenNonNull::new_unchecked()receives a null pointer after allocation failure.The prepared patch does two things:
hardens
CryptoVecitselfmlock/munlockno-opsunsafelocking callshardens the real untrusted-input path
256 * 1024on both client and server before resizing buffersThis cap matches OpenSSH’s agent framing guardrail.
PoC
The following end-to-end tests demonstrate the real untrusted-input path by feeding oversized peer-controlled agent frame lengths into the public client and server flows and asserting that they are rejected before buffer growth.
Client-side agent reply path:
Server-side agent request path:
These tests pass on the fixed branch and fail on unfixed
v0.60.2, where oversized agent frame lengths are not rejected at the framing boundary.For historical
russh < 0.58.0, I also verified remote reachability intoCryptoVecin a detached pre-712e32bworktree (91d431d, package version0.57.1).Transport packet read path:
Compression growth path:
Constrained-memory crash reproduction for the historical remote compression path:
On that historical worktree, the constrained-memory child aborts in the old Unix
CryptoVecpath with:To run the reproduced checks:
Historical pre-
0.58.0checks were run from the detached91d431dworktree with:Impact
This is a memory-safety hardening issue with demonstrated untrusted-input reachability.
What is demonstrated:
CryptoVecthrough transport and compression buffers inrussh < 0.58.0CryptoVeccodeWhat is not demonstrated:
Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:HReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Release Notes
warp-tech/russh (russh)
v0.60.3Compare Source
Security fixes
CVE-2026-46673
a2d48a7(Mika Cohen)When compression is negotiated, an attacker can craft a "ZIP bomb" style packet that would bypass the maximum packet size checks. This could allow the attacker to hit the OOM limit and either get the server process killed by the OS, or, prior to
russh@0.58.0, aborted. A similar issue existed in theAgentClientas well, which could be triggered by a malformed SSH agent response.v0.60.2Compare Source
Changes
Fixes
c31cbc9: Fix channel write ordering with pending data (#693) (Mika Cohen) #6932a49916: fixed #697 - pin all pre-release dependencies (Eugene)v0.60.1Compare Source
Security fixes
GHSA-f5v4-2wr6-hqmg in
6c3c80aThis DoS vulnerability allowed an unauthenticated user to trigger an out-of-memory condition in a russh based server if keyboard-interactive authentication is allowed. A malicious authentication packet could trigger a multi-GB memory allocation likely leading to the process getting killed by the OOM killer.
Fixes
a9057ed: fixed #687 - PKCS8 key encryption not working (#688) (Eugene) #688v0.60.0Compare Source
Changes
dad8de6: userand0.10 (#673) (Joe Grund) #673Fixes
v0.59.0Changes
6996711: Replace libcrux-ml-kem with RustCrypto ml-kem (#660) (kpcyrd) #660Fixes
084dbcf: Replace Deprecated Function Calls to criterion::black_box() (#683) (Roger Knecht) #683debc93c: Update dev-dependencies (env_logger, clap, termion) (#671) (kpcyrd) #67124d7527: Forward ChannelMsg::Close to channel before dropping sender (#674) (Corey Leavitt) #674bb9cc42: Fix and harden deferred channel EOF/CLOSE replay after rekey (#670) (Mika Cohen) #6703047787: Reduce size of ReadSshIdBuffer, add unit tests (#672) (kpcyrd) #672bcdc9b9: Bump aws-lc-rs to fix RUSTSEC-2026-0044 and RUSTSEC-2026-0048 (#681) (Roger Knecht) #681Misc
6270229: Update Rust dependencies (#676) (Roger Knecht) #676v0.58.0Compare Source
Changes
eliminate mlock/munlock overhead for non-secret buffers (~21% throughput improvement) (#653) #653 (Mika Cohen)
CryptoVec, reducing the performance overhead. A few public functions that tookCryptoVecnow takeimpl Into<Bytes>instead.6f70150: Remove heap allocations from SshId (#656) (kpcyrd) #656SshId::Standard()now contains aCow<'static, str>instead of aString.0f51860: Expose HostConfig fields to external consumers (#652) (François Bernier) #652e75de5a: Add russh/serde feature to enable serde onrussh::keys::PublicKey(#655) (kpcyrd) #655replace memset with zeroize in resize() method (#634) #634 (Eric Rodrigues Pires)
bump thiserror to latest version (#651) #651 (Roger Knecht)
b7ce487: Remove Home Crate Dependency (#667) (Roger Knecht) #667bebe8c0: fixed #658 - makeHandle::tcpip_forwardandHandle::streamlocal_forwardtake&self(Eugene)Fixes
aa43795: Harden Windows memory locking: fix ERROR_WORKING_SET_QUOTA and edge cases (#661) (Corey Leavitt) #661v0.57.1Compare Source
Fixes
46573ed: Fix zlib vs zlib@openssh.com compression timing (#564) (#646) (Guilherme Fontes) #646Features
591ec26: Improve CryptoVec performance (#627) (Eric Rodrigues Pires) #627Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.