Jun 26, 2026·7 min read·35 visits
Writing payloads larger than 4GB to a Go SSH channel causes integer truncation, leading to an infinite write loop and 100% CPU utilization on the executing thread.
A critical vulnerability exists in the Go SSH sub-repository (golang.org/x/crypto/ssh) before version 0.52.0. When an application writes payloads of 4GB or larger in a single write operation, integer truncation in the remote window calculation causes an infinite loop. This results in complete CPU core exhaustion and a denial-of-service condition.
The Go SSH sub-repository, distributed as part of golang.org/x/crypto/ssh, is widely used across the Go ecosystem to implement SSH clients, servers, and tunnels. A denial-of-service vulnerability, tracked as CVE-2026-39834 and GO-2026-5020, resides in the channel data transfer logic. The vulnerability occurs when transferring exceptionally large datasets over an established SSH channel.
The specific issue belongs to the class of integer overflow and truncation errors, cataloged as CWE-190. It manifests when an application calls write operations, such as Write or WriteExtended, with a payload slice size that exceeds the maximum bounds of a 32-bit unsigned integer (4 GiB, or 4,294,967,296 bytes). The vulnerability does not require authentication privileges if the application exposes a file upload or streaming endpoint that forwards user data into an SSH channel.
Upon encountering a 4 GiB write boundary, the internal packet-chunking logic truncates the calculated size of the next data packet to zero. Because the state machine receives a packet size of zero, it makes no progress through the data stream but continues to execute the write loop. The resulting execution loop runs indefinitely, pinning the affected CPU core to 100% capacity and degrading the performance or availability of the entire system.
The technical root cause of the vulnerability lies in the packet size calculation within ssh/channel.go. In the SSH protocol, large payloads are split into smaller chunks bounded by the remote party's maximum payload size and the available window space. This process is managed by an internal helper function called min in vulnerable versions.
The min function is defined with the signature func min(a uint32, b int) uint32. The first parameter a represents ch.maxRemotePayload, which is typically a uint32 variable. The second parameter b is the length of the remaining data slice (len(data)), which is of type int.
On 64-bit architectures, the Go native int type is a 64-bit signed integer. When a caller attempts to transmit a payload size of exactly $2^{32}$ bytes (4 GiB), b holds the value 4,294,967,296. The binary representation of this value is 0x100000000. When the code evaluates uint32(b), the cast drops the upper 32 bits of the 64-bit integer, resulting in a truncated value of 0.
Inside the comparison block, if a < uint32(b) compares the maximum payload size (for example, 32768) to the truncated value of 0. Because 32768 < 0 is false, the function executes the fallback branch and returns uint32(b), which is 0. Consequently, the allocation engine attempts to reserve zero bytes of window capacity and sends an empty packet. Since zero bytes are subtracted from the total remaining length of the payload, the write loop repeats indefinitely with the exact same variables, consuming 100% CPU.
To resolve the truncation defect, the Go security team implemented a fix in Change List 781663. The primary fix changes the comparison logic within ssh/channel.go to use 64-bit integer values, preventing truncation during the comparison phase. Additionally, the function was renamed to avoid namespace conflicts with Go's native built-in min function introduced in modern Go releases.
Below is the comparison of the vulnerable logic and the corrected implementation:
// VULNERABLE FUNCTION
func min(a uint32, b int) uint32 {
if a < uint32(b) {
return a
}
return uint32(b)
}
// PATCHED FUNCTION
// minPayloadSize returns min(limit, length) clamped to a uint32.
// The comparison is done in int64 because length is an int — on
// 64-bit systems len(data) can exceed 2^32, and a direct uint32(length)
// cast would silently truncate to 0 at every multiple of 2^32.
func minPayloadSize(limit uint32, length int) uint32 {
if int64(length) > int64(limit) {
return limit
}
return uint32(length)
}The corrected implementation casts both variables to int64 before conducting the comparison. Because int64 is capable of representing values up to $2^{63}-1$, the value of length (even when exceeding 4 GiB) is accurately preserved. If the remaining data size length is greater than the limit, the function safely returns the limit (which is already a uint32). If the remaining data size is smaller than the limit, it is guaranteed to fit within a uint32 variable, making the conversion safe from truncation.
Exploitation of CVE-2026-39834 requires the attacker to interact with an application that exposes an interface capable of sending data to an SSH channel. The host can be either an SSH client or an SSH server, meaning both outbound and inbound data flows are potentially vulnerable.
To trigger the denial-of-service condition, an attacker must cause the application to execute a single write call of size $n$, where $n$ is an exact multiple of 4 GiB, or slightly above 4 GiB such that the truncated value of b is smaller than the remote window payload threshold.
The vulnerability is triggered at the network boundaries. When the application receives the payload and passes it to the golang.org/x/crypto/ssh channel writer, the executing goroutine becomes stuck. No network errors or panics are thrown; the code simply spins, generating high CPU load. Since Go utilizes cooperative and pre-emptive scheduling, a single spinning goroutine will lock a complete OS thread, eventually degrading the availability of other application routines.
The impact of CVE-2026-39834 is classified as a high-severity Denial of Service (DoS). By utilizing relatively minor local resources to initiate a large file stream or data transfer, an attacker can consume all available CPU cycles on the target system. This causes complete resource exhaustion and halts other system operations.
The CVSS v3.1 score is evaluated at 9.1, reflecting the high availability impact and ease of execution over a network. Since the Go SSH package is the fundamental library for several high-profile infrastructure applications, the downstream impact is wide.
Affected downstream products include popular orchestrators, container engines, and cloud agents. Programs like Docker, containerd, HashiCorp Vault, Prometheus, and various cloud log-collection daemons are affected if they negotiate raw data channels via SSH with untrusted endpoints. In multi-tenant environments, a single user running an exploit against an SSH-based service could cause a complete service disruption for all other tenants sharing the same physical host.
The definitive remediation for this vulnerability is to upgrade the golang.org/x/crypto dependency to version v0.52.0 or higher. This update introduces the fixed minPayloadSize logic, which natively handles sizes larger than 4 GiB without truncation.
For systems where immediate upgrades are not possible, defensive mitigations can be applied at the application layer. Implementing application-level chunking ensures that no single call to channel.Write() exceeds a safe limit, such as 1 GiB.
// Application-level safety wrapper
func SafeChannelWrite(ch ssh.Channel, data []byte) (int, error) {
const maxChunkSize = 1024 * 1024 * 1024 // 1 GiB
total := 0
for len(data) > 0 {
chunk := len(data)
if chunk > maxChunkSize {
chunk = maxChunkSize
}
n, err := ch.Write(data[:chunk])
total += n
if err != nil {
return total, err
}
data = data[n:]
}
return total, nil
}Additionally, system administrators should monitor for anomalous Go processes running at 100% CPU capacity with minimal network output. Static code analysis pipelines should be configured to run dependency check tools to identify packages importing vulnerable versions of the SSH library.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
golang.org/x/crypto Go Cryptography | < 0.52.0 | 0.52.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-190 |
| Attack Vector | Network |
| CVSS v3.1 Score | 9.1 (Critical) |
| EPSS Score | 0.00466 |
| Impact | Denial of Service (DoS) via 100% CPU exhaustion |
| Exploit Status | none |
| KEV Status | Not listed |
The software performs a calculation that can produce an integer overflow or wraparound, causing the logic to evaluate incorrectly or behave unpredictably.
An authentication bypass in the SiYuan personal knowledge management system before version 3.7.0 exposes a dynamic icon rendering endpoint. This endpoint processes client-supplied Go template directives. By submitting a crafted request, an unauthenticated remote attacker can leverage registered database template functions to execute arbitrary read-only SQL queries and exfiltrate workspace contents.
CVE-2026-54069 is a critical authentication bypass vulnerability in the SiYuan Note personal knowledge management system. The flaw is located in the HTTP server's middleware handling API authorization, which unconditionally trusts requests carrying a 'chrome-extension://' scheme in the Origin HTTP header, granting administrative access without validating API tokens.
CVE-2026-54089 is a critical authentication bypass vulnerability in File Browser affecting instances configured with proxy-based authentication. An unauthenticated remote attacker with direct network access can impersonate arbitrary users or register new accounts by spoofing configured HTTP headers.
The malicious Cargo package 'exploration' was uploaded to the crates.io registry. During compilation or package import, the crate executes code designed to establish an outbound TCP/HTTP connection, download an external second-stage binary, and execute the binary locally on the host machine. This creates an unauthenticated remote code execution vector impacting developer environments and continuous integration pipelines.
CVE-2026-54088 is a critical command injection vulnerability in File Browser prior to version 2.63.6. When Hook Authentication is enabled, the application interpolates unsanitized credentials into a shell command, allowing unauthenticated remote code execution.
An authenticated remote code execution vulnerability exists in NotrinosERP (versions up to and including 1.0.0) within the Human Resource Management (HRM) module. Users with employee management permissions can upload arbitrary file types, including PHP scripts, which are written directly to a web-accessible directory. This allows for arbitrary code execution in the context of the web-server user.