Jun 26, 2026·7 min read·2 visits
Unauthenticated remote attackers can crash Go-based SSH servers or clients using AES-GCM ciphers by exploiting an integer overflow in padding length checks.
A high-severity Denial of Service (DoS) vulnerability (CVE-2026-46597 / GO-2026-5013) exists in the golang.org/x/crypto/ssh module before version v0.52.0. The flaw stems from an incorrect operator order during a type conversion of the GCM packet padding size, allowing a remote, unauthenticated attacker to trigger an out-of-bounds slice runtime panic and crash the Go process.
CVE-2026-46597 (also tracked as GO-2026-5013) is a high-severity Denial of Service (DoS) vulnerability in the golang.org/x/crypto/ssh module, Go's official cryptographic sub-repository. The vulnerability stems from an improperly validated length parameter inside the AES-GCM packet decoding routines. This flaw allows a remote, unauthenticated attacker to systematically trigger an unhandled runtime panic, crashing the underlying process.
The attack surface of this vulnerability is critical because it resides in the transport layer of the SSH protocol. A malicious client does not need to authenticate to trigger the defect. The vulnerability is reachable as long as the SSH server and client successfully complete the initial key exchange (KEX) and negotiate the use of AES-GCM mode.
Because the golang.org/x/crypto repository serves as the foundational package for SSH capabilities across the Go ecosystem, its impact extends far beyond standard SSH servers. Cloud infrastructure agents, container runtimes, continuous delivery agents, and security tools that leverage these libraries to establish secure tunnels are equally exposed. An unhandled panic in these components results in immediate service disruption.
Although there are currently no verified reports of active exploitation in the wild, the underlying logic flaw is predictable and reproducible. The absence of complex environmental requirements or race conditions makes constructing a functional exploit straightforward. Organizations utilizing Go-based custom SSH daemons must evaluate their exposure immediately.
The vulnerability is located in the packet validation logical sequence within ssh/cipher.go. When processing incoming packets under the AES-GCM cipher, the library must verify that the length of the declared padding is valid before stripping it from the plaintext payload. The developer implemented a safety validation check, but the expression was flawed due to improper operator precedence during type conversion.
The vulnerable code evaluates the expression int(padding+1) >= len(plain). Because the padding variable is defined as a uint8 (the Go standard alias for a raw byte), the addition operation padding+1 occurs before the conversion to the platform's native int. Consequently, the addition uses 8-bit unsigned integer arithmetic, which is subject to wrap-around behavior.
If an attacker constructs an SSH packet where the padding byte is set to 255 (hexadecimal 0xFF), the arithmetic addition 255 + 1 overflows the 8-bit limit. This results in a value of 0 before the type conversion to a native int is performed. The check resolves to 0 >= len(plain), which evaluates to false for any non-empty buffer, thereby bypassing the length validation check entirely.
Having bypassed the validation, execution continues to the slicing assignment: plain = plain[1 : length-uint32(padding)]. Under normal operations, this slice shortens the buffer to exclude the padding. When padding is 255 and length is small, the calculation length - 255 triggers an unsigned 32-bit integer underflow, producing a large positive number like 4294967051. Slicing a buffer with an index of this magnitude forces the Go runtime to trigger a slice bounds out of range panic, terminating the process.
The core issue in the vulnerable implementation resides inside the packet parsing logic of the GCM cipher module. The following code demonstrates how the compiler was instructed to handle the padding length validation check before the patch was applied:
// Vulnerable Implementation
if int(padding+1) >= len(plain) {
return nil, fmt.Errorf("ssh: padding %d too large", padding)
}
plain = plain[1 : length-uint32(padding)]When compiling the code above, the compiler generates assembly that performs the addition in the register representing the padding variable (a single-byte register). Because the addition occurs inside the parenthesis of int(...), the value of padding is not sign-extended or zero-extended to a wider integer type prior to the operation. This is why the value wraps back to 0, leading directly to the logical bypass.
The official patch introduces a simple yet robust change to the operator precedence. By moving the parentheses, the developer forces the compiler to cast the single-byte padding variable to a native signed integer type before performing the addition:
diff --git a/ssh/cipher.go b/ssh/cipher.go
index ad2b370..48d0199 100644
--- a/ssh/cipher.go
+++ b/ssh/cipher.go
@@ -407,7 +407,7 @@
return nil, fmt.Errorf("ssh: illegal padding %d", padding)
}
- if int(padding+1) >= len(plain) {
+ if int(padding)+1 >= len(plain) {
return nil, fmt.Errorf("ssh: padding %d too large", padding)
}
plain = plain[1 : length-uint32(padding)]With the updated code int(padding)+1, the uint8 value 255 is first safely expanded to a 32-bit or 64-bit signed integer value of 255. The subsequent addition of 1 evaluates to 256 without any possibility of overflow. The check 256 >= len(plain) evaluates to true, causing the function to safely return a structured error and cleanly teardown the network connection without crashing the host.
Exploitation of this vulnerability requires network access to the target SSH port. No valid credentials, SSH keys, or administrative privileges are needed to execute the attack. The attacker must first initiate a standard SSH-2.0 handshake and negotiate the use of an AES-GCM cipher suite, such as aes128-gcm@openssh.com or aes256-gcm@openssh.com.
Once the cryptographic tunnel is established, the attacker crafts a malicious SSH transport packet. The payload must be structured with specific parameters: the initial byte defining the padding length must be set to 255, and the overall transport layer packet length must be kept small. The attacker encrypts this structured payload using the session keys negotiated during the handshake.
The attacker transmits the ciphertext payload over the established TCP socket. Upon receipt, the server's GCM implementation decodes the block and authenticates the message using the GCM tag. Because the ciphertext itself is validly encrypted and signed, the packet easily passes initial integrity and authentication boundaries, proceeding directly to the parsing layer.
The server decrypts the payload and accesses the vulnerable code path in readPacket. The integer overflow bypasses the validation boundaries, and the subsequent slice calculation underflows, requesting an impossible memory boundary from the array. The Go runtime immediately throws a panic, killing the application worker process and severing all other concurrent connections.
The impact of CVE-2026-46597 is confined to system availability. Because the vulnerability triggers an immediate, unhandled runtime panic, it does not allow arbitrary code execution (RCE) or information disclosure. The CVSS v3.1 score of 7.5 reflects this high impact on availability (A:H) combined with low complexity (AC:L) and no privilege requirements (PR:N).
The actual blast radius of this vulnerability is amplified by the widespread usage of the golang.org/x/crypto/ssh package in cloud-native tools. Systems orchestration engines, serverless runners, continuous delivery daemons, and database proxies rely on this library to provide programmatic SSH access. A single unauthenticated attack packet can crash an entire control plane component, leading to wider operations failure.
Unlike standard daemon applications compiled in languages like C/C++ which might have supervisor-managed thread termination, an unhandled panic in Go terminates the entire application process, not just the executing goroutine. If the host application is not running under a strict container orchestration loop (such as Kubernetes with automated restart policies), the service remains down until manual intervention occurs.
The primary remediation strategy is upgrading the golang.org/x/crypto dependency to version v0.52.0 or later. This is accomplished by modifying the go.mod file of the affected project, running the command go get golang.org/x/crypto@v0.52.0, and executing go mod tidy. Developers must then recompile and redeploy all instances of the application.
In environments where recompilation is not immediately possible, administrators can mitigate the vulnerability by adjusting the cipher suites of their SSH services. Disabling the negotiation of AES-GCM ciphers (e.g., aes128-gcm@openssh.com, aes256-gcm@openssh.com) and preferring ChaCha20-Poly1305 ensures the vulnerable code path is never traversed.
Security teams can detect exploitation attempts by inspecting application logs for specific Go stack traces. A successful attack will write a diagnostic dump to standard error containing panic: runtime error: slice bounds out of range originating from golang.org/x/crypto/ssh.(*gcmCipher).readPacket in cipher.go. Automated log analysis tools should be configured to flag these panic events for rapid triage.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
golang.org/x/crypto Go | < v0.52.0 | v0.52.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-191 / CWE-704 |
| Attack Vector | Network (AV:N) |
| CVSS v3.1 Score | 7.5 (High) |
| EPSS Score | 0.00359 (27.78% percentile) |
| Impact | Complete Denial of Service (A:H) |
| Exploit Status | Unproven / No Public PoC |
| CISA KEV Status | Not Listed |
An integer value is decremented or subtracted such that it falls below its minimum representable value, resulting in a large positive integer wrap-around.
A critical security flaw was identified in the Go package golang.org/x/crypto/ssh/agent. The vulnerability arises during the serialization of key constraints when adding SSH identities to a remote agent or an in-memory keyring. Specifically, custom constraint extensions, such as destination restrictions like restrict-destination-v00@openssh.com, were silently omitted from serialization in client requests. This omission allowed keys to be loaded into the remote agent with zero destination-based restrictions, enabling unauthorized users with access to the agent socket on intermediate hosts to authenticate to any downstream host without policy enforcement. The issue was resolved in version v0.52.0 of the golang.org/x/crypto library.
A critical security bypass vulnerability was discovered in the Go SSH server implementation within the golang.org/x/crypto/ssh package. When an SSH server authentication callback returned a PartialSuccessError alongside non-nil Permissions, the server silently discarded these permissions before the subsequent authentication step. Consequently, once the user completed the second-factor authentication, the session-level restrictions were dropped, granting the client unauthorized capabilities.
A Denial of Service (DoS) vulnerability exists in the Go SSH implementation package (golang.org/x/crypto/ssh). The vulnerability is caused by a null pointer dereference (runtime panic) when CertChecker is utilized as a public key callback but its validation fields, IsUserAuthority or IsHostAuthority, are uninitialized.
An unbounded memory leak vulnerability in the Go SSH package (golang.org/x/crypto/ssh) allows authenticated users to crash the server by repeatedly requesting connection channels that are rejected, leading to system resource exhaustion.
A denial-of-service (DoS) and resource leak vulnerability in the Go SSH package (golang.org/x/crypto/ssh) allows a malicious peer to permanently deadlock connection processing loops and leak memory. This issue stems from improper handling of unsolicited responses at the global and channel layers, which saturate internal bounded channel buffers and block the main multiplexer loop. The vulnerability is fully resolved in version 0.52.0.
A high-severity Denial of Service (DoS) vulnerability exists in the golang.org/x/crypto/ssh package prior to version 0.52.0. The vulnerability is caused by a lack of size and range validation on incoming RSA and DSA public key parameters during SSH authentication. An unauthenticated attacker can submit a crafted public key with pathologically large parameters, triggering intensive CPU computation during signature verification and leading to a complete Denial of Service.