Jun 26, 2026·7 min read·45 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 symbolic link directory traversal vulnerability was identified in go-git, a pure Go implementation of the Git specification. This vulnerability allows an attacker to construct a repository that, when checked out or processed, bypasses directory boundaries to write or overwrite arbitrary files on the host filesystem.
CVE-2026-71557 is a path traversal vulnerability in go-git, a pure-Go implementation of Git. In vulnerable versions, the filesystem-backed storage engine fails to validate reference names before mapping them to on-disk paths. An attacker hosting a malicious Git server can advertise references containing directory traversal sequences, such as 'refs/heads/../../config', to write or overwrite files outside the intended reference storage directory.
An information disclosure vulnerability in the Nuxt development server allows adjacent network attackers to retrieve the absolute project root directory and a persistent workspace UUID by querying the unprotected Chrome DevTools workspace endpoint. This occurs when the development server is bound to a network-reachable interface, allowing requests that bypass the header-based security verification checks.
A Regular Expression Denial of Service (ReDoS) vulnerability exists in SvelteKit's content negotiation header parser prior to version 2.70.2. An unauthenticated remote attacker can exploit this vulnerability by sending a crafted Accept header with highly repetitive malformed values. This triggers catastrophic backtracking on the single-threaded Node.js/Bun event loop, leading to CPU exhaustion and full denial of service.
An OS command injection vulnerability exists in the npm package loading component of the jsii-diff CLI tool within the AWS jsii framework. Prior to version 1.131.0, when parsing package specifiers prefixed with `npm:`, the tool concatenated user-controlled inputs directly into a shell execution string via child_process.exec. This allows attackers to execute arbitrary shell commands under the context of the running Node.js process.
CodeIgniter4 versions prior to v4.7.4 contain a protocol-spoofing vulnerability due to improper verification of upstream reverse proxy forwarding headers. Remote, unauthenticated attackers can inject headers like X-Forwarded-Proto to deceive the framework into identifying an insecure HTTP request as a secure HTTPS connection.