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

CVE-2026-19931: Unauthenticated Session Reuse Vulnerability in libcurl Negotiate Implementation

Alon Barad
Alon Barad
Software Engineer

Sep 17, 2026·8 min read·5 visits

Executive Summary (TL;DR)

A session reuse vulnerability in libcurl allows requests with blank Negotiate credentials to hijack previously authenticated connections of other users, bypassing server-side authentication controls entirely.

A critical connection reuse vulnerability exists in curl and libcurl between versions 7.64.1 and 8.21.0 inclusive when Negotiate authentication (SPNEGO) is configured with blank credentials. Because libcurl fails to track changes to the underlying operating system's ambient security context, persistent authenticated connections are incorrectly matched and shared between distinct user sessions, allowing subsequent users to execute requests with the authorization state of the prior user.

Vulnerability Overview

The vulnerability CVE-2026-19931 represents a structural flaw in how libcurl maintains and evaluates cached persistent connections authenticated via the Negotiate (SPNEGO) protocol. Under normal operational parameters, libcurl attempts to optimize network efficiency by retaining authenticated connections in an internal connection pool (cpool). When a application initiates a new HTTP request, libcurl inspects this pool to determine if an existing connection to the same endpoint can be safely reused.

This reuse logic depends on matching not only transport parameters like hostnames, ports, and protocols, but also security credentials. If a cached connection is authenticated under User A's identity, libcurl must reject matches for requests issued by User B. However, when Negotiate authentication is initiated with empty or blank credentials (signified by CURLOPT_USERPWD set to ":"), libcurl delegates the authentication challenge to the host operating system's ambient security provider, such as the Security Support Provider Interface (SSPI) on Windows or GSSAPI libraries on Unix-like platforms.

Because libcurl does not actively monitor changes to the ambient security context of the system or the active thread executing the request, it operates under the flawed assumption that all empty-credential requests originate from the same user context. This creates an attack surface in multi-threaded, impersonated, or multi-user applications where the calling security context changes dynamically. In these scenarios, a connection established by a highly privileged user can be matched and reused by a subsequent unprivileged user whose request is routed over the existing, pre-authenticated socket.

Root Cause Analysis

To trace the root cause of CVE-2026-19931, it is necessary to examine the evolution of Negotiate connection handling in libcurl. The flaw was introduced in commit 6c6035532383e300c712e4c1cd9fdd749ed5cf59, which decoupled the Negotiate authentication state (negotiatedata) from the transfer-specific structure (UrlState) and attached it directly to the connection-bound structure (connectdata). Prior to this commit, libcurl terminated the underlying TCP connection as soon as a Negotiate-authenticated transfer was complete, neutralizing any possibility of accidental reuse.

The migration of negotiatedata allowed libcurl to preserve established Negotiate TCP connections in the pool. When validating cached connections for potential reuse, libcurl utilizes the internal function url_match_auth_nego(). This function verifies that the authentication configuration of the active request aligns with that of the cached connection. However, the logic contained an explicit bypass: if conn->creds (representing the cached credentials) was evaluated as NULL, the function skipped any rigorous credential comparison, assuming that both connections used the identical, static ambient user context.

In multi-user systems or server-side application environments executing thread-level impersonation, this assumption is false. On Windows platforms, threads may dynamically impersonate distinct security principles via APIs like ImpersonateLoggedOnUser(). Similarly, Unix systems using GSSAPI may swap Kerberos credential caches (indicated by the KRB5CCNAME environment variable) between operations. Because the libcurl engine is blind to these external operating system-level state transitions, it incorrectly considers any two requests utilizing "blank credentials" as structurally equivalent. When User B issues a request to the same target host, the caching engine identifies the host match, evaluates conn->creds == NULL, ignores the identity divergence, and assigns User B's transfer to the socket authenticated as User A.

Code Path and Patch Analysis

The remediation of this flaw was committed by Stefan Eissing in commit 7103a93b05bc69ea98ed9d05d02fa9eeba533f2f. The security patch addresses an architectural error in how libcurl handles connection management. Previously, connection maintenance tasks (such as connection pool upkeep, liveliness checks, and eviction strategies) were executed directly on the application handle (data) supplied by the calling thread. This pattern caused the application handle to temporarily bind to connections it was not actively utilizing, altering the state trackers and breaking the validation logic of data->state.recent_conn_id.

By running maintenance routines on the calling transfer handle, libcurl created a race and corruption scenario in connection matching. The patch introduces a dedicated, internal admin handle exclusively for administrative and maintenance operations, ensuring that user transfers never interact with or pollute the states of inactive cached connections. This separation preserves the integrity of recent_conn_id tracking, ensuring that connections are only eligible for reuse if they perfectly align with the calling user's isolated context.

// Conceptual representation of the fix in connection state binding
 
// BEFORE THE PATCH:
// Connection cleanup and maintenance routines were run on the active user context 'data'.
// This allowed state overlap and corrupts the connection validation markers.
CURLcode Curl_conn_cache_maintenance(struct Curl_easy *data) {
  // State modification occurs on user-controlled handle
  data->state.recent_conn_id = ...;
  return CURLE_OK;
}
 
// AFTER THE PATCH:
// Maintenance is isolated using an internal administrative handle ('admin_data').
// User-specific transfer contexts remain completely separated from idle pooled sockets.
CURLcode Curl_conn_cache_maintenance(struct Curl_easy *admin_data) {
  if(admin_data->internal_admin_handle) {
    // Execute maintenance without touching active user handle states
    perform_maintenance_tasks(admin_data);
  }
  return CURLE_OK;
}

Additionally, this fix prevents the session-matching bypass because the internal states are no longer scrambled by background eviction loops. By maintaining strict separation of administrative contexts, the socket validation engine can reliably enforce credential verification boundaries.

Exploitation Methodology

Exploitation of CVE-2026-19931 does not require complex cryptographic attacks or memory corruption payloads; instead, it relies on the predictable behavior of the connection matching engine. The exploit scenario operates in environments where libcurl is integrated into a multi-threaded daemon, a web application gateway, or a middleware service that performs actions on behalf of multiple users using Integrated Windows Authentication (IWA) or Kerberos SSO.

To trigger the session hijack, an attacker must satisfy the following prerequisites:

  1. The victim application must use libcurl versions between 7.64.1 and 8.21.0.
  2. The application must be configured to use Negotiate authentication (CURLOPT_HTTPAUTH set to CURLAUTH_NEGOTIATE).
  3. The application must omit explicit credentials, configuring empty username/password strings (CURLOPT_USERPWD set to ":"), thereby delegating to ambient Kerberos/GSSAPI contexts.
  4. The target server must support persistent HTTP connections (Keep-Alive).

The attack flow begins when User A (with high-level privileges) triggers an action. The application, impersonating User A, initiates a request through libcurl. The underlying GSSAPI/SSPI provider generates the required token, completes the handshake, and authenticates the TCP connection. The transaction finishes, and libcurl returns the connection to the pool. Next, User B (the attacker) initiates a transaction to the same server. The application switches thread context to User B and triggers a libcurl request. libcurl queries the pool, finds User A's idle, authenticated connection, matches it due to the NULL credential check bypass, and routes User B's request over it. The server processes User B's request under User A's identity, resulting in unauthenticated privilege escalation.

Impact Assessment and Severity

The impact of CVE-2026-19931 is rated Critical, with a CVSS v3.1 Base Score of 9.8. This score reflects the complete compromise of confidentiality, integrity, and availability within the trust boundary established between the client application and the backend service.

Because the session reuse bypass occurs entirely at the protocol transport layer within libcurl, security logging on the target server will not record any anomaly during the attack. The server simply receives a standard HTTP request over an already established, trusted TCP session that was authenticated during the initial SPNEGO handshake. Consequently, audit trails will attribute the attacker's unauthorized activities to the victim (User A), complicating incident response and forensics analysis.

In corporate environments, where Negotiate/Kerberos authentication is standard for single sign-on (SSO) to intranet portals, document management systems, and administrative APIs, this vulnerability exposes backend infrastructures to complete compromise. An attacker with low-privileged access to an application server can hijack active administrative connections to execute arbitrary state modifications, extract sensitive database files, or disable system availability.

Remediation and Mitigation Strategies

The primary resolution for CVE-2026-19931 is upgrading the libcurl binary to version 8.22.0 or higher. For deployments where legacy or enterprise-stable releases are required, organizations must apply backported security updates containing the fix, such as versions 8.20.1, 8.16.1, or 8.14.2.

If compiling from source or updating packages is not immediately feasible, developers can apply an application-level workaround. This workaround prevents libcurl from caching or reusing persistent connections that utilize Negotiate authentication. By setting the CURLOPT_FORBID_REUSE parameter to 1L on every easy handle that performs Negotiate requests with blank credentials, the library is forced to close the TCP connection immediately upon completion of the transfer. This eliminates the risk of pool pollution and unauthorized reuse.

// Secure implementation of ambient Negotiate authentication to mitigate CVE-2026-19931
CURL *curl = curl_easy_init();
if(curl) {
  curl_easy_setopt(curl, CURLOPT_URL, "https://internal-api.corp.local/data");
  
  // Configure SPNEGO / Negotiate authentication
  curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_NEGOTIATE);
  
  // Explicitly use blank credentials for ambient user context delegation
  curl_easy_setopt(curl, CURLOPT_USERPWD, ":");
  
  // MITIGATION: Disable socket persistence to prevent downstream connection reuse hijacking
  curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1L);
  
  CURLcode res = curl_easy_perform(curl);
  curl_easy_cleanup(curl);
}

Security teams should also review authorization structures on the backend servers. Where possible, configuring the backend to require re-authentication per request (by disabling HTTP Keep-Alive or using transaction-scoped tokens) can serve as an additional defense-in-depth measure.

Fix Analysis (2)

Technical Appendix

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

Affected Systems

curllibcurlSoftware applications using libcurl for HTTP-based Windows Integrated Authentication (SSPI/GSSAPI)

Affected Versions Detail

Product
Affected Versions
Fixed Version
curl
curl
>= 7.64.1, <= 8.21.08.22.0
libcurl
curl
>= 7.64.1, <= 8.21.08.22.0
AttributeDetail
CWE IDCWE-488 (Exposure of Data Element to Wrong Session)
Attack VectorNetwork (AV:N)
CVSS v3.1 Score9.8 (Critical)
EPSS Score0.01162 (Percentile: 65.60%)
Exploit StatusProof-of-Concept / Analysis
CISA KEV StatusNot Listed
Affected Version Range7.64.1 to 8.21.0

MITRE ATT&CK Mapping

T1556Modify Authentication Process
Credential Access
T1134Access Token Manipulation
Defense Evasion
CWE-488
Exposure of Data Element to Wrong Session

The product associates a system resource or data element with the incorrect session, leading to exposure of information or control to an unauthorized user.

Known Exploits & Detection

HackerOneOriginal security disclosure highlighting session reuse vulnerabilities in dynamic thread environments

Vulnerability Timeline

Vulnerability reported confidentially to the curl project via HackerOne by Martin Dukek
2026-08-07
Technical fix developed and committed by Stefan Eissing
2026-08-13
Coordinated disclosure. curl version 8.22.0 is released containing the fix
2026-09-02
National Vulnerability Database (NVD) publishes the vulnerability metadata
2026-09-06

References & Sources

  • [1]Official Curl Security Advisory
  • [2]Curl Advisory JSON Metadata
  • [3]HackerOne Original Disclosure Report (#3923520)
  • [4]Official Fix Commit
  • [5]Vulnerable Code Insertion Commit

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-61597
5.1

CVE-2026-61597: Cross-Site Scripting (XSS) via Unsanitized URI Schemes in djust Component Template Tags

Prior to version 1.0.7, the djust Python package is vulnerable to Stored and Reflected Cross-Site Scripting (XSS) via component template tags. The underlying issue exists because the package fails to sanitize or validate incoming URI schemes when rendering URLs inside interactive HTML attributes like href or action. While the framework HTML-escapes strings to prevent attribute breakout, it permits the execution of arbitrary JavaScript via the javascript: pseudo-protocol.

Amit Schendel
Amit Schendel
0 views•5 min read
•about 2 hours ago•CVE-2026-61592
7.4

CVE-2026-61592: Session Hijacking and Authorization Bypass in djust SSE Transport

A high-severity session hijacking and authorization bypass vulnerability has been identified in the djust framework prior to version 1.0.7. The flaw resides in the Server-Sent Events (SSE) transport implementation, which keyed sessions solely by client-provided session identifiers without verifying session ownership or binding. This allows an attacker who possesses or guesses a victim's session identifier to send malicious post messages to execute arbitrary state machine event handlers under the identity and permissions of the victim.

Alon Barad
Alon Barad
2 views•6 min read
•about 3 hours ago•CVE-2026-61591
8.1

CVE-2026-61591: State Snapshot Injection and Mass Assignment in djust Framework

CVE-2026-61591 is a high-severity state injection and authorization bypass vulnerability affecting the djust framework's opt-in State Snapshot feature. Prior to version 1.0.7, the framework restored public view state snapshots returned from the client browser during back-navigation without validating their cryptographic authenticity or integrity. This flaw allows malicious clients to manipulate serialized JSON payloads to inject unauthorized properties, leading to mass assignment (CWE-915) and privilege escalation. Version 1.0.7 addresses this issue by introducing HMAC cryptographic signatures bound to both the view configuration and the user's session identifier.

Amit Schendel
Amit Schendel
3 views•6 min read
•about 4 hours ago•CVE-2026-61588
6.5

CVE-2026-61588: Sensitive Data Exposure via Over-Serialization in djust Framework

A sensitive data exposure vulnerability exists in the djust framework before version 1.0.7. When serializing Django models to public view attributes, the framework fails to filter out sensitive fields such as passwords, privilege flags, and private tokens, leading to over-serialization and exposure of sensitive records to the client browser.

Amit Schendel
Amit Schendel
4 views•7 min read
•about 5 hours ago•CVE-2026-61596
7.1

CVE-2026-61596: Broken Object-Level Access Control (IDOR) in djust Framework

A broken object-level access control (IDOR) vulnerability exists in the djust Django framework prior to version 1.0.7. The framework's per-object authorization hooks were enforced correctly over WebSockets but entirely bypassed on synchronous HTTP GET rendering, SPA client-side navigation, and embedded sub-views, allowing authenticated attackers to view arbitrary unauthorized database records.

Alon Barad
Alon Barad
4 views•5 min read
•about 6 hours ago•CVE-2026-61589
6.3

CVE-2026-61589: Host Header Propagation Failure in djust WebSocket Live Path Reconstructor

CVE-2026-61589 is a security-bypass and information-disclosure vulnerability in the djust library prior to version 1.0.7. The library's WebSocket live path component fails to propagate the client HTTP Host header when dynamically reconstructing Django HttpRequest objects. Consequently, multi-tenant Django applications that rely on Host-based resolution may fail to isolate data correctly under certain configurations, leading to unauthorized cross-tenant data access.

Alon Barad
Alon Barad
3 views•6 min read