CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-39832

CVE-2026-39832: Silent Drop of Destination Constraints in golang.org/x/crypto SSH Agent Client

Amit Schendel
Amit Schendel
Senior Security Researcher

Jun 26, 2026·7 min read·2 visits

Executive Summary (TL;DR)

An issue in the Go SSH agent client silently drops custom key constraints during serialization, allowing attackers on a compromised jump host to reuse forwarded keys without restrictions and bypass security boundaries.

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.

Vulnerability Overview

The golang.org/x/crypto/ssh/agent package provides Go implementations of the SSH agent client and an in-memory SSH keyring. Developers utilize this library to manage SSH keys, establish connections, and handle key forwarding programmatically. The package serves as a critical component in custom SSH clients, deployment orchestrators, and system management tools that interact with remote infrastructure.\n\nUnder standard operational parameters, SSH key forwarding allows an intermediate system, such as a jump host or bastion host, to utilize the user's local SSH agent to authenticate subsequent connections. To protect against intermediate server compromise, the OpenSSH agent protocol introduces key constraints. These constraints restrict when, where, and how a forwarded identity can be utilized.\n\nThe vulnerability, identified as CVE-2026-39832, represents a breakdown in the enforcement of these security boundaries. The Go SSH agent client silently dropped modern key constraints, specifically those involving destination restrictions, during network serialization. Consequently, keys intended for highly constrained, single-hop usage were loaded into remote agents without any protective boundaries, exposing downstream environments to unauthorized lateral movement.

Root Cause Analysis

The root cause of CVE-2026-39832 lies in the client-side serialization routine within Go's SSH agent implementation. When a Go client adds an identity to an agent via the SSH_AGENTC_ADD_ID_CONSTRAINED request, it must serialize all associated constraints into a binary stream. The standard constraints include parameters such as lifetime limitations and explicit user confirmation prompts.\n\nModern versions of the OpenSSH agent protocol implement a generic constraint extension mechanism, denoted by the constraint type SSH_AGENT_CONSTRAINT_EXTENSION (byte value 255). This mechanism enables the transmission of arbitrary, named extensions, such as restrict-destination-v00@openssh.com. This specific extension restricts signature requests to designated hosts and users, mitigating risks associated with compromised intermediate hops.\n\nIn vulnerable versions of the golang.org/x/crypto library, the key serialization logic did not contain the switch cases or handlers required to recognize the generic SSH_AGENT_CONSTRAINT_EXTENSION type. When generating the byte payload, the client parsed standard constraint structures but skipped any element containing custom extension data. Because the serializer did not raise an error or halt execution, it generated an apparently valid network packet that omitted the constraints entirely.\n\nAdditionally, the in-memory keyring implementation provided by agent.NewKeyring() exhibited a complementary flaw. When applications loaded keys with custom constraint extensions into the keyring, the keyring.Add method silently ignored the unsupported extension fields rather than raising an error. This behavior compounded the severity of the flaw, creating a systemic failure to enforce security boundaries across both client-server and in-memory contexts.

Code Analysis

To understand the technical manifestation of the bug, we examine how the constraints were parsed and serialized into the network packet. Prior to the fix, the serialization loop in the client only processed standard, legacy constraints. Below is a representation of the vulnerable code pattern where the extension type is not accounted for:\n\ngo\n// VULNERABLE: Only standard constraints are checked\nfunc marshalConstraints(constraints []agent.Constraint) []byte {\n var out []byte\n for _, c := range constraints {\n switch c.Type {\n case agent.SSH_AGENT_CONSTR_LIFETIME:\n out = append(out, agent.SSH_AGENT_CONSTR_LIFETIME)\n out = appendUint32(out, c.Lifetime)\n case agent.SSH_AGENT_CONSTR_CONFIRM:\n out = append(out, agent.SSH_AGENT_CONSTR_CONFIRM)\n // Missing case for SSH_AGENT_CONSTRAINT_EXTENSION (255)\n // Custom extensions like restrict-destination are silently ignored\n }\n } return out\n}\n\n\nThe corresponding patch introduced proper handling for custom extension types. It ensures that any constraint of type SSH_AGENT_CONSTRAINT_EXTENSION is serialized using its name and string payload format. The updated serialization logic behaves as follows:\n\ngo\n// PATCHED: Support for extension constraints added\nfunc marshalConstraints(constraints []agent.Constraint) []byte {\n var out []byte\n for _, c := range constraints {\n switch c.Type {\n case agent.SSH_AGENT_CONSTR_LIFETIME:\n out = append(out, agent.SSH_AGENT_CONSTR_LIFETIME)\n out = appendUint32(out, c.Lifetime)\n case agent.SSH_AGENT_CONSTR_CONFIRM:\n out = append(out, agent.SSH_AGENT_CONSTR_CONFIRM)\n case agent.SSH_AGENT_CONSTRAINT_EXTENSION: // Added in v0.52.0\n out = append(out, agent.SSH_AGENT_CONSTRAINT_EXTENSION)\n out = appendString(out, c.ExtensionName)\n out = appendString(out, c.ExtensionDetails)\n }\n } return out\n}\n\n\nFurthermore, the patch modified the keyring's behavior. The in-memory keyring now explicitly evaluates incoming constraints and rejects keys if they contain unrecognized or unsupported extensions. This ensures that if the system cannot enforce the security policy, it fails closed rather than silently downgrading the security state of the key:\n\ngo\n// PATCHED Keyring enforcement: fail-closed on unknown constraints\nif len(key.Constraints) > 0 {\n for _, c := range key.Constraints {\n if !isSupportedConstraint(c) {\n return errors.New(\"ssh: unsupported agent constraint extension\")\n }\n }\n}\n

Exploitation & Attack Path

Exploitation of CVE-2026-39832 does not require the attacker to modify network packets in transit or exploit memory safety bugs. Instead, the vulnerability relies on the inherent behavior of the client silently stripping policy definitions, which results in the deployment of an over-privileged agent session on a target host.\n\nAn attack scenario typically unfolds within an enterprise jump host environment. A systems administrator connects to a compromise-vulnerable bastion server using a custom Go-based SSH client. Because the administrator wants to restrict the risk of key hijacking, they specify a destination constraint on their SSH key, restricting usage exclusively to production database server db-prod-01.internal.\n\nmermaid\ngraph LR\n Client[\"Go SSH Client (Vulnerable)\"] -->|\"Stripped Constraints\"| Bastion[\"Bastion Server (Compromised Agent)\"]\n Attacker[\"Attacker on Bastion (Root/Session Hijack)\"] -->|\"Reads Agent Socket\"| Bastion\n Attacker -->|\"Unrestricted Auth\"| ProdServer[\"Downstream Production Server (Any Destination)\"]\n\n\nWhen the client transmits the key during connection setup, the destination restrictions are completely excluded from the payload. The SSH agent running on the bastion host registers the key as an unrestricted identity. If an attacker has compromised the bastion host (either through root escalation or by gaining access to the user's local socket path), they can intercept the active agent socket.\n\nBecause the constraint is absent, the attacker can leverage the active session to connect to any other accessible server (e.g., internal-billing-01.internal or domain-controller.internal) that trusts the administrator's key. The agent on the bastion host processes the signature requests without checking the destination, executing the authentication successfully and allowing lateral movement across the internal network.

Impact Assessment

The impact of CVE-2026-39832 is designated as Critical, with a CVSS v3.1 base score of 9.1. The primary consequence is the total defeat of destination-based access controls within forwarded SSH agent sessions. Organizations that design their security architectures around the assumption that jump hosts cannot abuse forwarded credentials are majorly exposed to lateral movement risks.\n\nFrom a technical perspective, confidentiality and integrity are heavily impacted. An attacker who gains control of a jump host can capture the cryptographic authority of any user currently connected through a vulnerable Go client. This allows the attacker to execute remote commands, extract sensitive databases, and modify security configurations on any server that trusts the user's SSH key, regardless of any policy restrictions the user attempted to enforce.\n\nDespite the severity of this design flaw, the vulnerability requires a pre-existing presence on the intermediate host or access to the agent socket. The lack of active exploitation in public databases, combined with an EPSS score of 0.00397, suggests that mass automated exploitation is unlikely. However, targeted post-exploitation scenarios within enterprise networks represent a significant threat vector.

Remediation & Verification

The definitive remediation for CVE-2026-39832 is upgrading the golang.org/x/crypto dependency to version v0.52.0 or later. This upgrade ensures that custom agent extensions are serialized properly and that the in-memory keyring rejects keys with un-enforceable constraints.\n\nDevelopers should verify their codebase dependencies using the Go vulnerability scanner, govulncheck. This tool statically analyzes binaries and source code to identify calls to the affected symbols, such as client.Add and keyring.Add. To perform this validation, run the following command in the project root:\n\nbash\ngovulncheck ./...\n\n\nIf the upgrade cannot be performed immediately, several temporary workarounds can mitigate the risk. First, disable agent forwarding entirely in configuration files if it is not strictly necessary. Second, limit user access to intermediate jump hosts and audit socket permissions to prevent unauthorized processes from reading SSH agent sockets. Finally, utilize standard OpenSSH client binaries for operations requiring strict destination-based access controls, as they are unaffected by this serialization omission.

Official Patches

GoGerrit Code Review Fix Commit

Fix Analysis (1)

Technical Appendix

CVSS Score
9.1/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
EPSS Probability
0.40%
Top 68% most exploited

Affected Systems

golang.org/x/crypto/ssh/agent

Affected Versions Detail

Product
Affected Versions
Fixed Version
golang.org/x/crypto
Go
< 0.52.00.52.0
AttributeDetail
CWE IDCWE-281
Attack VectorNetwork
CVSS v3.1 Score9.1
EPSS Score0.00397 (Percentile: 31.59%)
ImpactUnrestricted lateral movement via forwarded SSH keys
Exploit StatusProof of Concept
CISA KEV StatusNot Listed

MITRE ATT&CK Mapping

T1563Remote Service Session Hijacking
Lateral Movement
T1021.004Remote Services: SSH
Lateral Movement
CWE-281
Improper Preservation of Permissions

The product does not preserve the original permissions of an object when transmitting or copying it, resulting in the object being accessible with wider privileges than intended.

Vulnerability Timeline

Vulnerability reported to Go Security team
2026-05-16
Public advisory GO-2026-5006 published
2026-05-22
CVE-2026-39832 assigned
2026-05-22
NVD database record updated with metrics
2026-06-17

References & Sources

  • [1]Go Vulnerability Database Report
  • [2]Go Issue Tracker #79435
  • [3]Gerrit Code Review Fix Commit CL 778642
  • [4]Official Golang Announcement
  • [5]CVE-2026-39832 Record

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 2 hours ago•CVE-2026-46597
7.5

CVE-2026-46597: Remote Denial of Service in golang.org/x/crypto/ssh via AES-GCM Padding Integer Overflow

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.

Alon Barad
Alon Barad
3 views•7 min read
•about 6 hours ago•CVE-2026-39828
6.3

CVE-2026-39828: Go SSH Server PartialSuccessError Permissions Discard Bypass

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.

Amit Schendel
Amit Schendel
5 views•7 min read
•about 7 hours ago•CVE-2026-39835
5.3

CVE-2026-39835: Remote Denial of Service via Null Pointer Dereference in Go SSH CertChecker

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.

Amit Schendel
Amit Schendel
8 views•7 min read
•about 7 hours ago•CVE-2026-39827
6.5

CVE-2026-39827: Denial of Service via Unbounded Memory Growth in Go SSH (golang.org/x/crypto/ssh)

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.

Amit Schendel
Amit Schendel
7 views•6 min read
•about 8 hours ago•CVE-2026-39830
9.1

CVE-2026-39830: Unsolicited Response Channel Deadlock and Resource Leak in golang.org/x/crypto/ssh

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.

Alon Barad
Alon Barad
5 views•7 min read
•about 10 hours ago•CVE-2026-39829
7.5

CVE-2026-39829: Denial of Service in Go SSH Parser

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.

Alon Barad
Alon Barad
6 views•5 min read