From 34799a59b82428f62a68857991d1e89ed462cf35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arthur=20Woimb=C3=A9e?= Date: Wed, 4 Jun 2025 12:36:54 +0200 Subject: [PATCH 1/2] fix CVE-2024-47081 --- src/requests/utils.py | 10 +--------- tests/test_utils.py | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/requests/utils.py b/src/requests/utils.py index 699683e5d9..2a217af293 100644 --- a/src/requests/utils.py +++ b/src/requests/utils.py @@ -236,16 +236,8 @@ 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] - try: - _netrc = netrc(netrc_path).authenticators(host) + _netrc = netrc(netrc_path).authenticators(ri.hostname) if _netrc: # Return with login / password login_i = 0 if _netrc[0] else 1 diff --git a/tests/test_utils.py b/tests/test_utils.py index 5e9b56ea64..f9a287af1b 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -23,6 +23,7 @@ get_encoding_from_headers, get_encodings_from_content, get_environ_proxies, + get_netrc_auth, guess_filename, guess_json_utf, is_ipv4_address, @@ -152,6 +153,24 @@ def test_super_len_with_no_matches(self): assert super_len(object()) == 0 +class TestGetNetrcAuth: + def test_works(self, tmp_path, monkeypatch): + netrc_path = tmp_path / ".netrc" + monkeypatch.setenv("NETRC", str(netrc_path)) + with open(netrc_path, "w") as f: + f.write("machine example.com login aaaa password bbbb\n") + auth = get_netrc_auth("http://example.com/thing") + assert auth == ("aaaa", "bbbb") + + def test_not_vulnerable_to_bad_url_parsing(self, tmp_path, monkeypatch): + netrc_path = tmp_path / ".netrc" + monkeypatch.setenv("NETRC", str(netrc_path)) + with open(netrc_path, "w") as f: + f.write("machine example.com login aaaa password bbbb\n") + auth = get_netrc_auth("http://example.com:@evil.com/'") + assert auth is None + + class TestToKeyValList: @pytest.mark.parametrize( "value, expected", From db5e9b8beb80dd22b64296ab4c7e8571f7ee593c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arthur=20Woimb=C3=A9e?= Date: Wed, 4 Jun 2025 12:37:40 +0200 Subject: [PATCH 2/2] rm workaround not needed since py38 --- src/requests/utils.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/requests/utils.py b/src/requests/utils.py index 2a217af293..53eb6fe2aa 100644 --- a/src/requests/utils.py +++ b/src/requests/utils.py @@ -219,14 +219,7 @@ def get_netrc_auth(url, raise_errors=False): netrc_path = None for f in netrc_locations: - try: - loc = os.path.expanduser(f) - except KeyError: - # os.path.expanduser can fail when $HOME is undefined and - # getpwuid fails. See https://bugs.python.org/issue20164 & - # https://github.com/psf/requests/issues/1846 - return - + loc = os.path.expanduser(f) if os.path.exists(loc): netrc_path = loc break