Security context
Medium· 5.3GHSA-9hjg-9r4m-mvj7 CVE-2024-47081CWE-522Published Jun 9, 2025

Requests vulnerable to .netrc credentials leak via malicious URLs

Research this vulnerability

Research is free — Hunters explains how the bug works, the root-cause code pattern, how the fix addresses it, and how to test whether a target is affected, in chat. Investigate & write exploit is a paid run — the engine reads the advisory and fix commits, then builds and validates a working proof-of-concept exploit with reproduction steps.

Affected versions

0 → fixed in 2.32.4

Details

### Impact Due to a URL parsing issue, Requests releases prior to 2.32.4 may leak .netrc credentials to third parties for specific maliciously-crafted URLs. ### Workarounds For older versions of Requests, use of the .netrc file can be disabled with `trust_env=False` on your Requests Session ([docs](https://requests.readthedocs.io/en/latest/api/#requests.Session.trust_env)). ### References https://github.com/psf/requests/pull/6965 https://seclists.org/fulldisclosure/2025/Jun/2

The fix

Only use hostname to do netrc lookup instead of netloc

Nate Prewitt· Sep 25, 2024, 03:03 PM+1757acb7c26d
src/requests/utils.py+1 7
@@ -236,13 +236,7 @@ def get_netrc_auth(url, raise_errors=False):
return
ri = urlparse(url)
-
- # Strip port numbers from netloc. This weird `if...encode`` dance is
- # used for Python 3.2, which doesn't support unicode literals.
- splitstr = b":"
- if isinstance(url, str):
- splitstr = splitstr.decode("ascii")
- host = ri.netloc.split(splitstr)[0]
+ host = ri.hostname
try:
_netrc = netrc(netrc_path).authenticators(host)

Only use hostname to do netrc lookup instead of netloc

Nate Prewitt· Sep 25, 2024, 03:03 PM+1796ba401c12
src/requests/utils.py+1 7
@@ -236,13 +236,7 @@ def get_netrc_auth(url, raise_errors=False):
return
ri = urlparse(url)
-
- # Strip port numbers from netloc. This weird `if...encode`` dance is
- # used for Python 3.2, which doesn't support unicode literals.
- splitstr = b":"
- if isinstance(url, str):
- splitstr = splitstr.decode("ascii")
- host = ri.netloc.split(splitstr)[0]
+ host = ri.hostname
try:
_netrc = netrc(netrc_path).authenticators(host)

References