python-urllib3/backport-CVE-2023-43804-added-the-Cookie-to-the-list-of-headers.patch
chengyechun 8773098c29 backport CVE-2023-45803
(cherry picked from commit 3b6a7d6fdaf6014db14918e60e004e69317cfb32)
2023-11-03 14:22:03 +08:00

158 lines
6.6 KiB
Diff

From 01220354d389cd05474713f8c982d05c9b17aafb Mon Sep 17 00:00:00 2001
From: Seth Michael Larson <sethmichaellarson@gmail.com>
Date: Mon, 2 Oct 2023 11:43:46 -0500
Subject: [PATCH] Backport GHSA-v845-jxx5-vc9f (#3139)
Co-authored-by: Quentin Pradet <quentin.pradet@gmail.com>
Co-authored-by: Illia Volochii <illia.volochii@gmail.com>
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: