Jun 26, 2026·5 min read·4 visits
The Go SSH library failed to verify the User Presence (UP) flag on FIDO/U2F hardware security keys, allowing authentication to proceed without the required physical tap or touch confirmation.
An authentication bypass vulnerability was identified in the golang.org/x/crypto/ssh package. The library's verification logic for FIDO/U2F security keys failed to check the User Presence (UP) flag. This omission allows an attacker with access to a hardware token interface or an agent-forwarding socket to authenticate without physical user interaction.
The Go standard sub-repository module golang.org/x/crypto/ssh provides implementations of SSH client and server protocols. This module supports hardware-backed FIDO/U2F security keys, including sk-ecdsa-sha2-nistp256@openssh.com and sk-ssh-ed25519@openssh.com key types. These key types secure authentication by requiring physical confirmation from the user during the signing process.
The SSH protocol utilizes the security key to generate signatures that assert user presence. The vulnerability, tracked as CVE-2026-39831, resides in the signature validation logic. The package accepted signatures where the User Presence flag was not set, violating the FIDO/U2F protocol specification.
This logical omission allows for silent, unattended cryptographic operations. If an attacker gains unauthorized logical access to an active security key, they can authenticate to upstream SSH servers without triggering physical interaction alerts on the user's hardware token.
FIDO/U2F hardware security keys include an authenticator data flags byte within their signature payload. The least significant bit (bit 0, value 0x01) represents the User Presence (UP) flag. Hardware keys set this flag when a user performs a physical interaction, such as tapping or touching the key.
In vulnerable versions of golang.org/x/crypto/ssh, the Verify() method implemented for skECDSAPublicKey and skEd25519PublicKey parsed signature payloads into the internal structure skFields. The definition of skFields contains a Flags field of type byte. However, the validation loop failed to execute a bitwise AND operation (Flags & 0x01) to assert the presence of the UP bit.
As a consequence of this logical gap, the SSH server validated only the outer cryptographic signature. The server assumed that any signature generated by the hardware token implied physical touch. Because hardware keys can generate signatures without touch under specific administrative policies, the absence of this programmatic check created a mechanism to bypass physical confirmation entirely.
The root cause resides in ssh/keys.go, where the validation logic ignored the parsed flags. The patch committed in Gerrit Change List 781662 introduces a constant flagUserPresence and a corresponding validation step in both ECDSA and Ed25519 security key verification logic.
// Constant defined in the patch
const flagUserPresence = 0x01
var errSKMissingUserPresence = errors.New("ssh: signature missing required user presence flag")The Verify methods are updated to enforce this check. If the signature lacks the user presence flag and the key is not explicitly designated to bypass it, verification returns errSKMissingUserPresence:
// Vulnerable vs. Patched Verification Logic
func (k *skECDSAPublicKey) Verify(data []byte, sig *Signature) error {
// [Parsing logic matches skFields]
// PATCH: Validate presence of the UP bit
if skf.Flags&flagUserPresence == 0 && !k.noTouchRequired {
return errSKMissingUserPresence
}
// Reconstruct signed blob and verify cryptographic signature
return verifyECDSA(k.PublicKey, blob, sig)
}To retain compatibility with OpenSSH implementations that support non-interactive automation, the patch introduces the helper function noTouchAllowed. This function checks if the `
Exploitation of CVE-2026-39831 does not require complex cryptographic manipulation, but rather leverages the structural omission of the security flag. An attacker who has achieved logical access to a user's environment can utilize a compromised SSH agent or direct connection to a forwarded socket to perform an authentication attempt.
When a standard FIDO credential challenge is received, the attacker interacts with the token interface to request a signature with user presence set to false. Because the Go SSH library fails to inspect the flag, the connection is authorized automatically. This bypasses the multi-factor guarantee of physical presence, reverting the security model back to single-factor logical authentication.
The security implications of bypassing User Presence verification are severe. Hardware security keys are deployed to guarantee that remote attackers cannot use stolen cryptographic material without a physical gesture. This vulnerability completely invalidates that defense-in-depth design.
The Common Vulnerability Scoring System (CVSS) v3.1 base score is calculated as 9.1 (Critical), with the vector string CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N. Because the user interaction is programmatically bypassed, the User Interaction (UI) component of the vector drops from Required (R) to None (N).
If automated SSH administrative frameworks utilize vulnerable versions of this library, they are exposed to remote compromise. An attacker capable of intercepting authentication requests can establish persistent unauthorized administrative channels.
The primary remediation strategy is upgrading the golang.org/x/crypto dependency to version v0.52.0 or higher. This upgrade ensures that the golang.org/x/crypto/ssh package implements strict validation of the User Presence flag by default.
If upgrading immediately is not possible, security teams must audit their environments for the use of `
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
golang.org/x/crypto/ssh Go Language | < v0.52.0 | v0.52.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-290 |
| Attack Vector | Network |
| CVSS Base Score | 9.1 |
| EPSS Score | 0.00373 |
| Exploit Status | poc |
| CISA KEV Status | Not Listed |
The software-based verification mechanism did not check key cryptographic/FIDO metadata flags, trusting signatures that should have been rejected due to missing physical interaction confirmation.
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.
An issue was discovered in Go's `golang.org/x/crypto/ssh/knownhosts` package where a revoked Certification Authority (CA) public key was not correctly checked for revocation during SSH host certificate validation. This allowed clients or servers utilizing the library to validate and trust host certificates issued by explicitly revoked CAs.
An authorization bypass vulnerability exists in the golang.org/x/crypto/ssh package prior to version 0.52.0. When an SSH server is configured with a custom VerifiedPublicKeyCallback that returns a Permissions object containing a source-address critical option, the server fails to validate and enforce the restriction. This allows remote clients with valid public keys to bypass IP-based access restrictions and authenticate from unauthorized network locations.
A critical vulnerability exists in MessagePack-CSharp's typeless deserialization mechanism where configured blocklists fail to recursively inspect nested types. An attacker can bypass security restrictions by wrapping unauthorized types in arrays or generic collections, allowing insecure deserialization and remote code execution.
A critical prototype pollution vulnerability exists in the i18next-fs-backend Node.js package (prior to version 2.6.6) through its translation persistence layer. When handling missing translation keys, insecure traversal of JSON objects via the getLastOfPath function allows remote, unauthenticated attackers to mutate Object.prototype, potentially leading to denial of service, security bypasses, or remote code execution.
CVE-2026-48708 details a critical concurrency synchronization flaw in OliveTin versions < 3000.13.0. A shared package-level text/template.Template instance is accessed concurrently across multiple goroutines without proper synchronization. When concurrent request processing occurs, a race condition causes Go runtime panics or command contamination across separate sessions, enabling denial of service or execution of contaminated commands.