HexBrain

curl · Report #3677759

CVE-2026-6429: netrc credential leak with reused proxy connection

Validstatus
mediumseverity
19upvotes
29 Apr 2026disclosed

How it was found

Summary:

libcurl can leak .netrc-derived host Authorization credentials across redirected hosts when an HTTP proxy connection is reused. In the PoC, .netrc contains credentials only for a.test, but after a.test redirects to b.test and then c.test over the same keep-alive proxy connection, libcurl sends Authorization: Basic dXNlckE6cGFzc0E= to b.test and c.test. The leaked header is Authorization, not Proxy-Authorization, and the attached controls show the leak disappears when connection reuse is forbidden, when each request uses a new easy handle, and when the same redirect flow is run without a proxy. The issue appears to involve the .netrc / redirect / proxy connection reuse path in lib/url.c and lib/http.c. I reproduced this on curl 8.19.0 / libcurl 8.19.0 on x86_64 Linux. An attachment with the PoC source, server scripts, .netrc file, and captured logs is included.

Affected version

Reproduced on: curl 8.19.0 (x86_64-pc-linux-gnu) libcurl/8.19.0 OpenSSL/3.5.5 zlib/1.3.1 brotli/1.2.0 zstd/1.5.7 libidn2/2.3.8 libpsl/0.21.5 libssh2/1.11.1 nghttp2/1.68.1 ngtcp2/1.21.0 nghttp3/1.15.0 librtmp/2.3 mit-krb5/1.22.1 OpenLDAP/2.6.10 Platform: Linux x86_64

Steps To Reproduce:

  1. Ensure the attached .netrc file contains only: machine a.test login userA password passA
  2. Start the proxy/server: python3 -u netrc_proxy_redirect_server.py 18085
  3. Start the no-proxy origin control server: python3 -u netrc_origin_redirect_server.py 18087
  4. Build the PoC: cc poc_netrc_proxy_redirect.c -o poc_netrc_proxy_redirect $(curl-config --cflags --libs)
  5. Run the PoC: ./poc_netrc_proxy_redirect
  6. Observe the base case proxy log. a.test, b.test, and c.test all use the same client_port, showing proxy connection reuse, and the same host Authorization header is sent to all three hosts: {"client_port": 49048, "host": "a.test", "path": "http://a.test/start", "authorization": "Basic dXNlckE6cGFzc0E=", "proxy_authorization": null} {"client_port": 49048, "host": "b.test", "path": "http://b.test/second", "authorization": "Basic dXNlckE6cGFzc0E=", "proxy_authorization": null} {"client_port": 49048, "host": "c.test", "path": "http://c.test/third", "authorization": "Basic dXNlckE6cGFzc0E=", "proxy_authorization": null}
  7. Observe the controls:
    • with CURLOPT_FORBID_REUSE=1, b.test and c.test receive no Authorization
    • with a new easy handle per request, b.test and c.test receive no Authorization
    • without a proxy, b.test and c.test receive no Authorization
  8. The attached logs also show that Proxy-Authorization is always null, so the leaked header is the target-host Authorization header, not proxy credentials.

Impact

Summary:

An attacker-controlled redirected host reachable through the same HTTP proxy connection can receive .netrc credentials that belong to a different host. This is a cross-host credential boundary break: credentials configured only for a.test are sent as host Authorization to b.test and c.test, even though .netrc has no entries for those hosts. In applications that use libcurl with .netrc, redirects, and HTTP proxy connection reuse, this can expose reusable Basic credentials to an unintended origin.

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