curl · Report #3584903
CVE-2026-3784: wrong proxy connection reuse with credentials
How it was found
Summary
libcurl may reuse an existing HTTP proxy CONNECT tunnel without matching proxy credentials when selecting a reusable connection. In lib/url.c, url_match_proxy_use() calls proxy_info_matches() (lib/url.c:930-935 → lib/url.c:589-595), and that matcher compares proxy type, host, and port but does not compare proxy username or password. When a shared connection cache is used (CURLSH + CURL_LOCK_DATA_CONNECT), a transfer using different proxy credentials can reuse a previously authenticated tunnel. In my reproduction the proxy receives only one CONNECT request with good:good, while a second transfer configured with bad:bad succeeds through the existing tunnel without issuing a new CONNECT. This was reproduced both with sequential libcurl transfers and with a wrapper/daemon model where multiple clients submit jobs to a process holding the shared connection cache. Control tests show the issue does not occur when connections are not shared (noshare) or when the destination host differs.
Affected version Reproduced on: curl 8.18.0 (x86_64-pc-linux-gnu) libcurl/8.18.0 OpenSSL/3.5.5 zlib/1.3.1 brotli/1.2.0 zstd/1.5.7 libidn2/2.3.8 libpsl/0.21.2 libssh2/1.11.1 nghttp2/1.64.0 ngtcp2/1.16.0 nghttp3/1.12.0 librtmp/2.3 mit-krb5/1.22.1 OpenLDAP/2.6.10
Release information: Release-Date: 2026-01-07 security patched: 8.18.0-2 Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp ws wss Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTP3 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM PSL SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd
Steps To Reproduce
- Build the PoC program using libcurl.
- Start the local proxy reproducer script. python3 /tmp/run_share_connect_poc.py
- The script performs two transfers via a proxy. Transfer 1: proxy credentials: good:good Transfer 2: proxy credentials: bad:bad
MODE noshare
- first request succeeds
- second request fails with proxy authentication error
- proxy observes two CONNECT requests
MODE share
- both requests succeed
- proxy observes only one CONNECT request
- CONNECT uses good:good
- second request (bad:bad) is sent through existing tunnel Run the wrapper daemon scenario (curl_wrap_daemon.c) to simulate a service using a shared connection pool. The second client using bad:bad credentials still succeeds while the proxy sees only the original CONNECT.
Impact
When applications share a libcurl connection cache using CURLSHOPT_SHARE with CURL_LOCK_DATA_CONNECT, proxy authentication contexts can be mixed across requests.
A transfer specifying invalid proxy credentials may reuse a previously authenticated CONNECT tunnel established with different credentials.
In multi-tenant architectures or wrapper/daemon services that reuse a shared connection pool, this can allow requests to bypass proxy authentication policy enforcement.