critical · 9.1CVE-2026-39834Jun 25, 2026

CVE-2026-39834: golang.org/x/crypto/ssh Infinite Loop via Integer Overflow on Large Channel Write

Rohit Hatagale
AI Security Researcher, SecureLayer7

Integer overflow in golang.org/x/crypto/ssh channel.Write allows a caller to trigger an infinite loop by passing a single buffer >4 GiB, causing CPU exhaustion (DoS).

Packagegolang.org/x/crypto/ssh
Ecosystemgo
Affected< 0.52.0
Fixed in0.52.0
CVE-2026-39834: golang.org/x/crypto/ssh Infinite Loop via Integer Overflow on Large Channel Write

The problem

In golang.org/x/crypto/ssh versions before 0.52.0, the channel.Write and channel.WriteExtended methods computed a payload-size variable using a type narrower than 64 bits. When a single Write call passes a buffer larger than 4 GiB (> math.MaxUint32 bytes), the size value wraps around to zero or a small positive number, causing the write loop to spin indefinitely and emit empty SSH data packets without making forward progress.

Any process that proxies or streams large SSH payloads (e.g., SFTP bulk transfers, SSH tunnels) can be locked into 100% CPU consumption, constituting a remote denial-of-service.

Proof of concept

javascript
// Trigger: write a single buffer of exactly 1 byte over the 32-bit boundary
// Connect to any server using the vulnerable library, then on an open ssh.Channel:
buf := make([]byte, 1<<32) // 4 GiB + 1 byte triggers the overflow
_, err := ch.Write(buf)    // ch is an ssh.Channel
// The Write loop inside channel.go never terminates; CPU pegs at 100%

Before the fix, channel.WriteExtended (ssh/channel.go) calculated the per-packet size using an int (or int32 intermediate) variable. A buffer length of 4 GiB (0x100000000) truncates to 0 when cast to int32, so the loop guard `size > 0` evaluates false immediately on the first iteration yet the outer loop restarts unconditionally, spinning forever and emitting zero-length SSH_MSG_CHANNEL_DATA packets.

CL 781663 changes the size variable to int64, which holds values up to 9.2 EiB and eliminates the truncation path entirely. CWE-190 (Integer Overflow or Wraparound) applies: the signed/unsigned width mismatch between the slice length (int, 64-bit on amd64) and the internal counter (int32/int) is the root cause.

The fix

Upgrade golang.org/x/crypto to v0.52.0 or later (`go get golang.org/x/crypto@v0.52.0`). The fix in CL 781663 changes the payload-size comparison variable in ssh/channel.go from int to int64, preventing wraparound for any buffer up to 9.2 EiB. As a short-term workaround where upgrading is not immediately possible, applications should enforce a maximum single-Write buffer size below 2 GiB (e.g., chunk large transfers into <=32 MiB segments before passing them to ssh.Channel.Write).

Reported by NCC Group Cryptography Services (sponsored by Teleport).

References: [1][2][3][4][5][6]