diff --git a/requests/sessions.py b/requests/sessions.py index 6cb3b4dae3..dbcf2a7b0e 100644 --- a/requests/sessions.py +++ b/requests/sessions.py @@ -324,7 +324,9 @@ def rebuild_proxies(self, prepared_request, proxies): except KeyError: username, password = None, None - if username and password: + # urllib3 handles proxy authorization for us in the standard adapter. + # Avoid appending this to TLS tunneled requests where it may be leaked. + if not scheme.startswith('https') and username and password: headers["Proxy-Authorization"] = _basic_auth_str(username, password) return new_proxies diff --git a/tests/test_requests.py b/tests/test_requests.py index b1c8dd4534..b420c44d73 100644 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -647,6 +647,26 @@ def test_proxy_authorization_preserved_on_request(self, httpbin): assert sent_headers.get("Proxy-Authorization") == proxy_auth_value + + @pytest.mark.parametrize( + "url,has_proxy_auth", + ( + ('http://example.com', True), + ('https://example.com', False), + ), + ) + def test_proxy_authorization_not_appended_to_https_request(self, url, has_proxy_auth): + session = requests.Session() + proxies = { + 'http': 'http://test:pass@localhost:8080', + 'https': 'http://test:pass@localhost:8090', + } + req = requests.Request('GET', url) + prep = req.prepare() + session.rebuild_proxies(prep, proxies) + + assert ('Proxy-Authorization' in prep.headers) is has_proxy_auth + def test_basicauth_with_netrc(self, httpbin): auth = ("user", "pass") wrong_auth = ("wronguser", "wrongpass")