Jun 26, 2026·5 min read·41 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 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.