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-39828

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

Amit Schendel
Amit Schendel
Senior Security Researcher

Jun 26, 2026·7 min read·68 visits

Executive Summary (TL;DR)

A session state vulnerability in Go's SSH server package allows clients to bypass certificate restrictions (such as forced commands or client source IP bounds) during multi-factor authentication, resulting in unauthorized unrestricted access.

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.

Vulnerability Overview

The SSH protocol allows for multi-factor and multi-step authentication processes to verify a client's identity before establishing a session. In the Go programming language ecosystem, this protocol state machine is handled by the golang.org/x/crypto/ssh package, specifically within the custom SSH server interfaces. This architecture exposes a significant attack surface in systems that implement customized authentication steps, such as bastion hosts, jumping servers, or complex corporate infrastructure access portals.

The vulnerability is classified under CWE-863 (Incorrect Authorization) and CWE-295 (Improper Certificate Validation). It represents a structural flaw in how authentication state transitions manage session restrictions. Specifically, session constraints such as force-command or IP-source limitations are expressed via the Permissions structure in Go's SSH implementation. When these constraints are generated during intermediate phases of multi-step authentication, they are lost during subsequent authentication iterations.

This security degradation occurs silently, providing no feedback to the server operator or logging mechanisms that restrictions have been completely disabled. Because the final authentication success state is evaluated independently of previous step restrictions, the connection is authorized without the security policies that were bound to the client's initial credentials.

Root Cause Analysis

To understand the root cause of this vulnerability, we must examine the internal state machine managed by the serverAuthenticate function in the ssh/server.go file of the golang.org/x/crypto/ssh package. When processing multi-factor authentication, the server framework loops through a series of registered authentication callbacks. If a callback succeeds but requires additional steps, it returns a *PartialSuccessError. This error indicates that the current method is verified, but additional requirements from the PartialSuccessError.Next slice must be fulfilled.

During this iterative evaluation, the permissions variable tracks authorizations and restrictions returned by callbacks (such as VerifiedPublicKeyCallback or PublicKeyCallback). However, in vulnerable versions of the package, this variable is reset, shadowed, or overwritten at the start of each iteration in the authentication loop. When an intermediate authentication callback returned a *PartialSuccessError alongside a populated non-nil *Permissions struct, the Go SSH server failed to persist or merge these credentials into the active loop state.

As a direct result of this state discard, the permissions (including vital certificate extensions and critical restrictions) vanished. When the final factor (such as a TOTP token or a password callback) succeeded, it typically returned nil for permissions, assuming the previously established permissions were still active. The server then completed the handshake with the final nil permissions, granting the client an unconstrained SSH shell.

Code Analysis and State Mismatch

The critical logic flaw resided within the iterative client authentication handler loop in ssh/server.go. Below is a representation of the vulnerable code path versus the patched logic implemented in Gerrit Change 781621.

// VULNERABLE STATE HANDLING
for {
    // ...
    perms, authErr = authCallback(conn, user, authArgs)
    // ...
    if partialSuccess, ok := authErr.(*PartialSuccessError); ok {
        // BUG: The perms variable is returned by the callback here but is 
        // not preserved or merged for subsequent loop iterations.
        // It is silently dropped on the next loop iteration.
        partialSuccessReturned = true
        // ...
    }
}

The security patch resolves this state mismatch by ensuring that the implementation does not allow ambiguous states where developers attempt to return permissions during intermediate authentication stages. Rather than risking a complex state merge that could introduce further authorization bypass vulnerabilities, the Go security team adopted a fail-closed, strict API check. If any intermediate callback attempts to combine a PartialSuccessError with non-nil Permissions, the connection is immediately terminated with an error:

// PATCHED STATE HANDLING
if partialSuccess, ok := authErr.(*PartialSuccessError); ok {
    // Permissions are not preserved between authentication steps. To
    // avoid confusion about the final state of the connection, we
    // disallow returning non-nil Permissions combined with
    // PartialSuccessError.
    if perms != nil {
        return nil, errors.New("ssh: permissions must be nil when returning PartialSuccessError")
    }
    partialSuccessReturned = true
    // ...
}

This fix is highly complete because it eliminates the structural ambiguity at the API boundary. By throwing an explicit runtime error on misconfiguration, it prevents developers from inadvertently exposing their servers to silent credential degradation.

Exploit Methodology

Exploiting this vulnerability does not require complex cryptographic attacks. It relies entirely on structural path manipulation in custom SSH servers implementing multi-factor authentication. An attacker must possess valid credentials for the initial authentication method (such as an SSH private key matching a signed certificate containing restrictions) and the subsequent factor (such as a password or TOTP code).

To perform the attack, the adversary initiates an SSH connection using their restricted certificate. The custom server callback evaluates the certificate, establishes security permissions (such as force-command="/usr/bin/restricted_shell"), and returns a PartialSuccessError instructing the client to proceed to the next authentication method. Because of the bug, the server discards the force-command constraint. The attacker then provides the required MFA token. The server authenticates the MFA callback, verifies success, and completes the handshake. The attacker is then dropped into a standard interactive shell with unrestricted command execution capabilities, successfully escaping the forced command sandbox.

Impact Assessment

The impact of CVE-2026-39828 is substantial in enterprise and infrastructure-access contexts. Custom SSH portals, bastion hosts, and network gateways built on top of the Go x/crypto/ssh framework are frequently designed to isolate sensitive environments by mapping strict policies (e.g., preventing port forwarding, or restricting users to narrow administrative commands) directly onto user certificates. Discarding these permissions completely undermines the multi-layered security architecture of these access controls.

While the CVSS v3.1 base score is rated at 6.3 (Medium), the operational impact in customized environments can be critical. The score details point to Network (AV:N) access complexity, Low complexity (AC:L), and Low Privileges (PR:L) since the attacker needs basic credentials. However, because this vulnerability allows the bypass of the security perimeter designed to enforce restricted access control, it effectively transforms a restricted session into an unconstrained session.

Currently, there is no evidence of public exploitation or weaponized proof-of-concept tools. However, because the vulnerability relies entirely on logical code paths rather than memory unsafety, writing an exploit requires minimal effort for an attacker who already possesses initial access.

Mitigation and Remediation Guidance

The definitive remediation for CVE-2026-39828 is to upgrade the golang.org/x/crypto dependency to version v0.52.0 or higher. This upgrade forces the SSH server to abort any connection that returns an invalid combination of a PartialSuccessError and non-nil Permissions, preventing authorization degradation.

If immediate dependency updates are not viable, developers must inspect and modify their SSH server callback implementations. Specifically, ensure that any callback that returns a PartialSuccessError returns a nil pointer for the *Permissions parameter. All session permissions and certificate restrictions must be deferred and returned exclusively during the final, successful authentication callback that finishes the multi-step handshake.

Additionally, automated testing should be incorporated. Implement integrated integration tests that mimic multi-factor authentication sequences to verify that certificate extensions and restrictions are correctly preserved and actively enforced once the SSH session becomes active.

Fix Analysis (1)

Technical Appendix

CVSS Score
6.3/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L
EPSS Probability
0.18%
Top 93% most exploited

Affected Systems

Custom SSH servers built with golang.org/x/crypto/sshGo-based SSH portals and jump serversGo-based bastion hosts and network gateway controls

Affected Versions Detail

Product
Affected Versions
Fixed Version
golang.org/x/crypto
Go
< v0.52.0v0.52.0
AttributeDetail
CWE IDCWE-863 (Primary), CWE-295
Attack VectorNetwork
CVSS v3.16.3
EPSS Score0.00175 (7.12% percentile)
ImpactAuthorization Bypass / Privilege Escalation
Exploit StatusNone (No active public exploits)
KEV StatusNot listed

MITRE ATT&CK Mapping

T1556Modify Authentication Process
Credential Access
T1110Brute Force: Multi-Factor Authentication Bypass
Credential Access
CWE-863
Incorrect Authorization

The software performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly associate the constraints with the active session.

Vulnerability Timeline

Technical root cause identified and patch created by Nicola Murino
2026-02-01
Private security track tracking completed (Google Issue tracker reference: b/503007173)
2026-05-21
Advisory released under GO-2026-5014 and CVE-2026-39828. Patched module released
2026-05-22

References & Sources

  • [1]Go Issue Tracker Thread #79562
  • [2]Gerrit Code Review / Code Patch
  • [3]Go Vulnerability Advisory GO-2026-5014
  • [4]Golang Announce Mailing List

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 1 hour ago•CVE-2026-54892
8.7

CVE-2026-54892: Algorithmic Complexity Denial of Service in Plug Query Decoder

An algorithmic complexity vulnerability (CWE-407) in the query decoder of the Elixir Plug library (CVE-2026-54892) allows unauthenticated remote attackers to trigger scheduler starvation and denial of service by transmitting deeply nested brackets in query parameters or URL-encoded post bodies.

Alon Barad
Alon Barad
5 views•6 min read
•about 2 hours ago•CVE-2026-83801
5.4

CVE-2026-83801: Stored Cross-Site Scripting via Form Help Text in Nautobot

CVE-2026-83801 is a stored Cross-Site Scripting (XSS) vulnerability in Nautobot. The vulnerability arises because the application interpolates user-controlled database properties—specifically Relationship descriptions and Module Family names—directly into the help_text parameter of Django form fields. These fields are rendered using Django's |safe filter, bypassing HTML escaping and enabling persistent injection. When an administrative user accesses the affected forms, the payload executes contextually in their browser. This allows attackers to hijack active sessions and perform unauthorized operations. Nautobot versions prior to v2.4.37 and v3.1.8 are affected by this vulnerability. The issue has been patched by implementing contextual HTML escaping and strict markdown sanitization.

Alon Barad
Alon Barad
5 views•5 min read
•about 3 hours ago•CVE-2026-83805
6.4

CVE-2026-83805: Authorization Bypass and Privilege Escalation in Nautobot Approval Workflows

An authorization bypass vulnerability exists in Nautobot's REST API endpoints handling approval workflows. Due to an architectural inconsistency, a standalone, generic REST API endpoint for creating approval responses was exposed without propagating the required business-logic validations. This allows low-privileged authenticated users to submit forged, self-approved votes, bypassing approval thresholds and triggering unauthorized server-side automated jobs.

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

CVE-2026-85709: Sensitive Information Exposure in LightRAG API Server

CVE-2026-85709 is a sensitive information exposure vulnerability in HKUDS LightRAG prior to version 1.5.5. The vulnerability allows remote, unauthenticated clients to trigger server-side errors and receive raw Python exception details, including local filesystem paths, database connection strings, credentials, and internal system configurations.

Amit Schendel
Amit Schendel
5 views•6 min read
•about 5 hours ago•CVE-2026-85725
5.9

CVE-2026-85725: Observable Timing Side-Channel Vulnerability in HKUDS LightRAG

HKUDS LightRAG prior to version 1.5.5 is vulnerable to multiple timing side-channels (CWE-208) in its API authentication layer. The password verification logic in `lightrag/api/passwords.py` compares plaintext administrative credentials using Python's short-circuiting equality operator (`==`). Additionally, `lightrag/api/auth.py` terminates authentication early on non-existent usernames, creating an observable latency difference compared to computationally expensive bcrypt comparisons on valid accounts. Together, these allow remote unauthenticated attackers with low-latency network access to enumerate valid usernames and extract plaintext passwords character by character.

Amit Schendel
Amit Schendel
4 views•5 min read
•about 6 hours ago•CVE-2026-85734
9.1

CVE-2026-85734: Brute-Force and CPU-Exhaustion DoS in LightRAG API /login Endpoint

LightRAG prior to version 1.5.5 does not implement rate limiting, lockout mechanisms, or throttling on its `/login` authentication endpoint. This allows unauthenticated remote attackers to perform rapid brute-force attacks to crack passwords and hijack active sessions. Furthermore, because the endpoint processed synchronous bcrypt verifications inside an asynchronous event loop, concurrent brute-force requests can easily exhaust server CPU resources, triggering an unauthenticated Denial of Service (DoS).

Alon Barad
Alon Barad
5 views•5 min read