Negotiate connection reuse with wrong credentials when using CURLAUTH_ANY

Disclosed: 2026-04-29 07:16:09 By anonymous_237 To curl
Medium
Vulnerability Details
## Summary: CVE-2026-1965 fixed connection reuse for Negotiate authentication by adding url_match_auth_nego() in url_match_conn() at line 1244 of lib/url.c. When a first handle authenticates via Negotiate (Kerberos) on a connection and that connection returns to the pool, a second handle with different credentials should not reuse it. When the second handle uses CURLAUTH_NEGOTIATE with different credentials, here is what happens: url_match_auth_ntlm() at line 1239 returns TRUE (because want_ntlm_http is FALSE), so url_match_conn() does not stop and continues. It reaches url_match_auth_nego() at line 1244. This function compares the credentials at lines 1152-1153, finds they are different, and returns FALSE at line 1154. Back in url_match_conn(), this FALSE causes return FALSE to execute at line 1245. The connection is not saved in m->found. The fix works. However, when the second handle uses CURLAUTH_ANY (which includes both the NTLM and Negotiate bits ), want_ntlm_http is TRUE. url_match_auth_ntlm() enters its credential-mismatch path at line 1086. It checks conn->http_ntlm_state == NTLMSTATE_NONE at line 1091. On a connection authenticated via Negotiate, this condition is true because NTLM was never used. The function saves the connection in m->found = conn at line 1092, then returns FALSE at line 1093. Back in url_match_conn(), this FALSE causes return FALSE to execute at line 1240. The function url_match_conn() terminates here. url_match_auth_nego() at line 1244 is never called. After the pool iteration, url_match_result() at line 1267 only tests whether match->found is non-NULL. It is (saved at line 1092). Curl_attach_connection() is called at line 1270. The second handle is attached to the first handle's connection. On this connection, the Negotiate handshake is already completed (GSS_AUTHSUCC). Curl does not generate a new Authorization header (http_negotiate.c:254 sets authp->done = TRUE). The request is sent on a connection already authenticated under the first handle's identity. The root cause is line 1092: m->found = conn is set when http_ntlm_state == NTLMSTATE_NONE, without checking http_negotiate_state. ## Affected version: The vulnerability was identified by source code analysis of curl 8.20.0-DEV (master branch). ## Impact Same impact as CVE-2026-1965
Actions
View on HackerOne
Report Stats
  • Report ID: 3646072
  • State: Closed
  • Substate: duplicate
Share this report