Negotiate connection reuse with wrong credentials when using CURLAUTH_ANY
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 HackerOneReport Stats
- Report ID: 3646072
- State: Closed
- Substate: duplicate