From 01220354d389cd05474713f8c982d05c9b17aafb Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Mon, 2 Oct 2023 11:43:46 -0500 Subject: [PATCH] Backport GHSA-v845-jxx5-vc9f (#3139) Co-authored-by: Quentin Pradet Co-authored-by: Illia Volochii Conflict:NA Reference:https://github.com/urllib3/urllib3/commit/01220354d389cd05474713f8c982d05c9b17aafb --- src/urllib3/util/retry.py | 2 +- test/test_retry.py | 4 ++-- test/test_retry_deprecated.py | 2 +- test/with_dummyserver/test_poolmanager.py | 24 ++++++++++++++++++----- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/urllib3/util/retry.py b/src/urllib3/util/retry.py index 2490d5e5b6..60ef6c4f3f 100644 --- a/src/urllib3/util/retry.py +++ b/src/urllib3/util/retry.py @@ -235,7 +235,7 @@ class Retry(object): RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503]) #: Default headers to be used for ``remove_headers_on_redirect`` - DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(["Authorization"]) + DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(["Cookie", "Authorization"]) #: Maximum backoff time. DEFAULT_BACKOFF_MAX = 120 diff --git a/test/test_retry.py b/test/test_retry.py index 21ba1e92e1..95a33e7461 100644 --- a/test/test_retry.py +++ b/test/test_retry.py @@ -293,12 +293,12 @@ def test_retry_method_not_in_whitelist(self): def test_retry_default_remove_headers_on_redirect(self): retry = Retry() - assert list(retry.remove_headers_on_redirect) == ["authorization"] + assert retry.remove_headers_on_redirect == {"authorization", "cookie"} def test_retry_set_remove_headers_on_redirect(self): retry = Retry(remove_headers_on_redirect=["X-API-Secret"]) - assert list(retry.remove_headers_on_redirect) == ["x-api-secret"] + assert retry.remove_headers_on_redirect == {"x-api-secret"} @pytest.mark.parametrize("value", ["-1", "+1", "1.0", six.u("\xb2")]) # \xb2 = ^2 def test_parse_retry_after_invalid(self, value): diff --git a/test/test_retry_deprecated.py b/test/test_retry_deprecated.py index f55c5d846b..5133a51afa 100644 --- a/test/test_retry_deprecated.py +++ b/test/test_retry_deprecated.py @@ -295,7 +295,7 @@ def test_retry_method_not_in_whitelist(self): def test_retry_default_remove_headers_on_redirect(self): retry = Retry() - assert list(retry.remove_headers_on_redirect) == ["authorization"] + assert retry.remove_headers_on_redirect == {"authorization", "cookie"} def test_retry_set_remove_headers_on_redirect(self): retry = Retry(remove_headers_on_redirect=["X-API-Secret"]) diff --git a/test/with_dummyserver/test_poolmanager.py b/test/with_dummyserver/test_poolmanager.py index fa07a372a9..02a38115c5 100644 --- a/test/with_dummyserver/test_poolmanager.py +++ b/test/with_dummyserver/test_poolmanager.py @@ -141,7 +141,7 @@ def test_redirect_cross_host_remove_headers(self): "GET", "%s/redirect" % self.base_url, fields={"target": "%s/headers" % self.base_url_alt}, - headers={"Authorization": "foo"}, + headers={"Authorization": "foo", "Cookie": "foo=bar"}, ) assert r.status == 200 @@ -149,12 +149,13 @@ def test_redirect_cross_host_remove_headers(self): data = json.loads(r.data.decode("utf-8")) assert "Authorization" not in data + assert "Cookie" not in data r = http.request( "GET", "%s/redirect" % self.base_url, fields={"target": "%s/headers" % self.base_url_alt}, - headers={"authorization": "foo"}, + headers={"authorization": "foo", "cookie": "foo=bar"}, ) assert r.status == 200 @@ -163,6 +164,8 @@ def test_redirect_cross_host_remove_headers(self): assert "authorization" not in data assert "Authorization" not in data + assert "cookie" not in data + assert "Cookie" not in data def test_redirect_cross_host_no_remove_headers(self): with PoolManager() as http: @@ -170,7 +173,7 @@ def test_redirect_cross_host_no_remove_headers(self): "GET", "%s/redirect" % self.base_url, fields={"target": "%s/headers" % self.base_url_alt}, - headers={"Authorization": "foo"}, + headers={"Authorization": "foo", "Cookie": "foo=bar"}, retries=Retry(remove_headers_on_redirect=[]), ) @@ -179,6 +182,7 @@ def test_redirect_cross_host_no_remove_headers(self): data = json.loads(r.data.decode("utf-8")) assert data["Authorization"] == "foo" + assert data["Cookie"] == "foo=bar" def test_redirect_cross_host_set_removed_headers(self): with PoolManager() as http: @@ -186,7 +190,11 @@ def test_redirect_cross_host_set_removed_headers(self): "GET", "%s/redirect" % self.base_url, fields={"target": "%s/headers" % self.base_url_alt}, - headers={"X-API-Secret": "foo", "Authorization": "bar"}, + headers={ + "X-API-Secret": "foo", + "Authorization": "bar", + "Cookie": "foo=bar", + }, retries=Retry(remove_headers_on_redirect=["X-API-Secret"]), ) @@ -196,12 +204,17 @@ def test_redirect_cross_host_set_removed_headers(self): assert "X-API-Secret" not in data assert data["Authorization"] == "bar" + assert data["Cookie"] == "foo=bar" r = http.request( "GET", "%s/redirect" % self.base_url, fields={"target": "%s/headers" % self.base_url_alt}, - headers={"x-api-secret": "foo", "authorization": "bar"}, + headers={ + "x-api-secret": "foo", + "authorization": "bar", + "cookie": "foo=bar", + }, retries=Retry(remove_headers_on_redirect=["X-API-Secret"]), ) @@ -212,6 +225,7 @@ def test_redirect_cross_host_set_removed_headers(self): assert "x-api-secret" not in data assert "X-API-Secret" not in data assert data["Authorization"] == "bar" + assert data["Cookie"] == "foo=bar" def test_redirect_without_preload_releases_connection(self): with PoolManager(block=True, maxsize=2) as http: