HexBrain

curl · Report #3669637

CVE-2026-6253: proxy credentials leak over redirect-to proxy

Validstatus
mediumseverity
24upvotes
29 Apr 2026disclosed

How it was found

Summary:

When libcurl follows a redirect and the new URL causes proxy re-selection, proxy credentials learned from the originally selected proxy URL can remain in per-transfer state and be reused for the next proxy. In the validated case, a redirect from http:// to https:// switches selection from http_proxy to https_proxy, but credentials from http_proxy=http://user:pass@... are still sent to the https_proxy even when the https_proxy URL contains no credentials. A redirecting server can therefore cause libcurl to send Proxy-Authorization intended for proxy A to proxy B on proxy B’s first request. This appears limited to proxy credentials carried in transfer state, not the intentionally global CURLOPT_PROXYUSERNAME / CURLOPT_PROXYPASSWORD case. As a control, requesting the HTTPS URL directly with the same https_proxy does not send Proxy-Authorization to proxy B. I reproduced this on a local build and observed proxy B receive Proxy-Authorization: Basic dXNlcjpwYXNz on the initial CONNECT.

Affected version

Reproduced with: curl 8.20.0-DEV (Linux) libcurl/8.20.0-DEV OpenSSL/3.0.2 zlib/1.2.11 brotli/1.0.9 zstd/1.4.8 libidn2/2.3.2 libpsl/0.21.0 nghttp2/1.43.0 OpenLDAP/2.5.20

Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt mqtts pop3 pop3s rtsp smtp smtps telnet tftp ws wss

Features: alt-svc AsynchDNS brotli HSTS HTTP2 HTTPS-proxy IDN IPv6 Largefile libz PSL SSL threadsafe TLS-SRP UnixSockets zstd

Git commit used: 935e1f9963a12ac1a880df538b23b824d2fea7bb

Platform: Linux 6.8.0-1044-azure #50~22.04.1-Ubuntu SMP Wed Dec 3 15:13:22 UTC 2025 x86_64 GNU/Linux

Steps To Reproduce:

  1. Start an HTTP origin on 127.0.0.1:8000 that returns a redirect from /redir to https://127.0.0.1:8443/final.
  2. Start an HTTPS origin on 127.0.0.1:8443 that serves /final. Any certificate is sufficient; curl -k is enough for local reproduction.
  3. Start two HTTP-family proxies and log incoming request headers:
    • Proxy A on 127.0.0.1:8081
    • Proxy B on 127.0.0.1:8082
  4. Run:

http_proxy=http://user:[email protected]:8081
https_proxy=http://127.0.0.1:8082
/path/to/curl -k -L http://127.0.0.1:8000/redir

  1. Observe that the first HTTP request goes through proxy A and includes credentials for proxy A.
  2. After the redirect to https://127.0.0.1:8443/final, libcurl re-selects proxy B via https_proxy.
  3. Observe that proxy B receives a first request like:

CONNECT 127.0.0.1:8443 HTTP/1.1 Host: 127.0.0.1:8443 Proxy-Authorization: Basic dXNlcjpwYXNz User-Agent: curl/8.20.0-DEV Proxy-Connection: Keep-Alive

  1. As a control, if the same HTTPS URL is requested directly with only https_proxy=http://127.0.0.1:8082, proxy B does not receive Proxy-Authorization.

Impact

Summary:

A redirecting server can cause libcurl to disclose credentials intended for one proxy to a different proxy under separate administrative control. This crosses a real proxy trust boundary and can expose reusable proxy secrets. Because proxy auth defaults to Basic, an HTTP-family second proxy can receive Proxy-Authorization on the very first request once stale proxy credentials survive the redirect. The issue is security-relevant even though it requires redirect following and a proxy-selection change, because the disclosure is demonstrable and occurs before any authentication challenge from the second proxy.

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original