Skip to content

Commit

Permalink
Preserve Authorization header on HTTPS redirect (#1850) (#2074)
Browse files Browse the repository at this point in the history
* Preserve Authorization header on HTTPS redirect (#1850)

* Update httpx/_client.py

Co-authored-by: Tom Christie <tom@tomchristie.com>
  • Loading branch information
waterfountain1996 and tomchristie committed Feb 9, 2022
1 parent 4f8068a commit 4401d55
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 3 deletions.
8 changes: 5 additions & 3 deletions httpx/_client.py
Expand Up @@ -51,6 +51,7 @@
URLPattern,
get_environment_proxies,
get_logger,
is_https_redirect,
same_origin,
)

Expand Down Expand Up @@ -532,9 +533,10 @@ def _redirect_headers(self, request: Request, url: URL, method: str) -> Headers:
headers = Headers(request.headers)

if not same_origin(url, request.url):
# Strip Authorization headers when responses are redirected away from
# the origin.
headers.pop("Authorization", None)
if not is_https_redirect(request.url, url):
# Strip Authorization headers when responses are redirected
# away from the origin. (Except for direct HTTP to HTTPS redirects.)
headers.pop("Authorization", None)

# Update the Host header.
headers["Host"] = url.netloc.decode("ascii")
Expand Down
15 changes: 15 additions & 0 deletions httpx/_utils.py
Expand Up @@ -282,6 +282,21 @@ def same_origin(url: "URL", other: "URL") -> bool:
)


def is_https_redirect(url: "URL", location: "URL") -> bool:
"""
Return 'True' if 'location' is a HTTPS upgrade of 'url'
"""
if url.host != location.host:
return False

return (
url.scheme == "http"
and port_or_default(url) == 80
and location.scheme == "https"
and port_or_default(location) == 443
)


def get_environment_proxies() -> typing.Dict[str, typing.Optional[str]]:
"""Gets proxy information from the environment"""

Expand Down
18 changes: 18 additions & 0 deletions tests/client/test_redirects.py
Expand Up @@ -270,6 +270,15 @@ def test_cross_domain_redirect_with_auth_header():
assert "authorization" not in response.json()["headers"]


def test_cross_domain_https_redirect_with_auth_header():
client = httpx.Client(transport=httpx.MockTransport(redirects))
url = "http://example.com/cross_domain"
headers = {"Authorization": "abc"}
response = client.get(url, headers=headers, follow_redirects=True)
assert response.url == "https://example.org/cross_domain_target"
assert "authorization" not in response.json()["headers"]


def test_cross_domain_redirect_with_auth():
client = httpx.Client(transport=httpx.MockTransport(redirects))
url = "https://example.com/cross_domain"
Expand All @@ -287,6 +296,15 @@ def test_same_domain_redirect():
assert response.json()["headers"]["authorization"] == "abc"


def test_same_domain_https_redirect_with_auth_header():
client = httpx.Client(transport=httpx.MockTransport(redirects))
url = "http://example.org/cross_domain"
headers = {"Authorization": "abc"}
response = client.get(url, headers=headers, follow_redirects=True)
assert response.url == "https://example.org/cross_domain_target"
assert response.json()["headers"]["authorization"] == "abc"


def test_body_redirect():
"""
A 308 redirect should preserve the request body.
Expand Down
19 changes: 19 additions & 0 deletions tests/test_utils.py
Expand Up @@ -10,6 +10,7 @@
get_ca_bundle_from_env,
get_environment_proxies,
guess_json_utf,
is_https_redirect,
obfuscate_sensitive_headers,
parse_header_links,
same_origin,
Expand Down Expand Up @@ -221,6 +222,24 @@ def test_not_same_origin():
assert not same_origin(origin1, origin2)


def test_is_https_redirect():
url = httpx.URL("http://example.com")
location = httpx.URL("https://example.com")
assert is_https_redirect(url, location)


def test_is_not_https_redirect():
url = httpx.URL("http://example.com")
location = httpx.URL("https://www.example.com")
assert not is_https_redirect(url, location)


def test_is_not_https_redirect_if_not_default_ports():
url = httpx.URL("http://example.com:9999")
location = httpx.URL("https://example.com:1337")
assert not is_https_redirect(url, location)


@pytest.mark.parametrize(
["pattern", "url", "expected"],
[
Expand Down

0 comments on commit 4401d55

Please sign in to comment.