CVE-2026-6429: netrc credential leak with reused proxy connection
Medium
Vulnerability Details
## 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.
Actions
View on HackerOneReport Stats
- Report ID: 3677759
- State: Closed
- Substate: resolved