Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions Lib/test/test_urllib2.py
Original file line number Diff line number Diff line change
Expand Up @@ -1735,6 +1735,27 @@ def test_proxy_basic_auth(self):
"proxy.example.com:3128",
)

def test_proxy_basic_auth_ignores_direct_407(self):
# gh-158907: a direct HTTP origin that returns 407 must not receive
# credentials registered for the same authority over HTTPS.
opener = OpenerDirector()
opener.add_handler(urllib.request.ProxyHandler({}))
password_manager = urllib.request.HTTPPasswordMgr()
auth_handler = urllib.request.ProxyBasicAuthHandler(password_manager)
realm = "test-realm"
http_handler = MockHTTPHandlerRedirect(
407, 'Proxy-Authenticate: Basic realm="%s"\r\n\r\n' % realm)
opener.add_handler(auth_handler)
opener.add_handler(http_handler)

password_manager.add_password(
realm, "https://example.com/", "victim-user", "victim-secret")
opener.open("http://example.com/resource")

self.assertEqual(len(http_handler.requests), 1)
self.assertFalse(
http_handler.requests[0].has_header("Proxy-authorization"))

def test_basic_and_digest_auth_handlers(self):
# HTTPDigestAuthHandler raised an exception if it couldn't handle a 40*
# response (https://bugs.python.org/issue1479302), where it should instead
Expand Down
3 changes: 3 additions & 0 deletions Lib/urllib/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,9 @@ class ProxyBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler):
auth_header = 'Proxy-authorization'

def http_error_407(self, req, fp, code, msg, headers):
# gh-158907: a 407 from a direct origin is not a proxy challenge
if not req.has_proxy() and not req._tunnel_host:
return None
# http_error_auth_reqed requires that there is no userinfo component in
# authority. Assume there isn't one, since urllib.request does not (and
# should not, RFC 3986 s. 3.2.1) support requests for URLs containing
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
:class:`~urllib.request.ProxyBasicAuthHandler` no longer sends credentials
in response to ``407`` from a direct origin. A scheme-less lookup against
the origin host could match passwords stored for an HTTPS URL and retry
the cleartext request with ``Proxy-Authorization``.
Loading