[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1091087: marked as done (bookworm-pu: package python-urllib3/1.26.12-1+deb12u1)



Your message dated Sat, 11 Jan 2025 11:03:09 +0000
with message-id <E1tWZGn-009jak-DS@coccia.debian.org>
and subject line Close 1091087
has caused the Debian Bug report #1091087,
regarding bookworm-pu: package python-urllib3/1.26.12-1+deb12u1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
1091087: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1091087
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: bookworm
X-Debbugs-Cc: python-urllib3@packages.debian.org
Control: affects -1 + src:python-urllib3
User: release.debian.org@packages.debian.org
Usertags: pu

[ Reason ]

Fix 3 no-dsa vulnerabilities (CVE-2023-43804, CVE-2023-45803 and
CVE-2024-37891) and a bug where urllib3.util.ssltransport fails to load
(#1089507).

[ Impact ]

Bookworm users will remain vulnerable.  Also the issues were fixed in
Bullseye LTS, so users upgrading to Bookworm will regress if it isn't
fixed to that suite too.

[ Tests ]

The 3 vulnerabilities come with unit tests.  ssltransport.py is covered
by unit tests too; those ones are currently ignored at build time and
autopkgtests, but were tested manually.

[ Risks ]

The fixes are trivial: 1.26.x is officially supported upstream and the
patches were backported to 1.26.12 without conflict.

[ Checklist ]

  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in stable
  [x] the issue is verified as fixed in unstable

[ Changes ]

  * Fix CVE-2023-43804: Cookie request header isn't stripped during
    cross-origin redirects. (Closes: #1053626)
  * Fix CVE-2023-45803: Request body not stripped after redirect from 303
    status changes request method to GET. (Closes: #1054226)
  * Fix CVE-2024-37891: Proxy-Authorization request header isn't stripped
    during cross-origin redirects. (Closes: #1074149)
  * Use system 'six' module in urllib3.util.ssltransport. (Closes: #1089507)
  * Fix test/test_connectionpool.py (currently ignored).
  * Adjust d/salsa-ci.yml for bookworm.
  * Adjust d/gbp.conf for bookworm.

-- 
Guilhem.
diffstat for python-urllib3-1.26.12 python-urllib3-1.26.12

 changelog                                       |   16 ++
 gbp.conf                                        |    2 
 patches/01_do-not-use-embedded-python-six.patch |   23 ++-
 patches/CVE-2023-43804.patch                    |  157 +++++++++++++++++++++
 patches/CVE-2023-45803.patch                    |  177 ++++++++++++++++++++++++
 patches/CVE-2024-37891.patch                    |  164 ++++++++++++++++++++++
 patches/series                                  |    3 
 salsa-ci.yml                                    |    5 
 8 files changed, 541 insertions(+), 6 deletions(-)

diff -Nru python-urllib3-1.26.12/debian/changelog python-urllib3-1.26.12/debian/changelog
--- python-urllib3-1.26.12/debian/changelog	2022-09-22 23:14:17.000000000 +0200
+++ python-urllib3-1.26.12/debian/changelog	2024-12-21 15:28:17.000000000 +0100
@@ -1,3 +1,19 @@
+python-urllib3 (1.26.12-1+deb12u1) bookworm; urgency=medium
+
+  * Non-maintainer upload.
+  * Fix CVE-2023-43804: Cookie request header isn't stripped during
+    cross-origin redirects. (Closes: #1053626)
+  * Fix CVE-2023-45803: Request body not stripped after redirect from 303
+    status changes request method to GET. (Closes: #1054226)
+  * Fix CVE-2024-37891: Proxy-Authorization request header isn't stripped
+    during cross-origin redirects. (Closes: #1074149)
+  * Use system 'six' module in urllib3.util.ssltransport. (Closes: #1089507)
+  * Fix test/test_connectionpool.py (currently ignored).
+  * Adjust d/salsa-ci.yml for bookworm.
+  * Adjust d/gbp.conf for bookworm.
+
+ -- Guilhem Moulin <guilhem@debian.org>  Sat, 21 Dec 2024 15:28:17 +0100
+
 python-urllib3 (1.26.12-1) unstable; urgency=medium
 
   * Team upload.
diff -Nru python-urllib3-1.26.12/debian/gbp.conf python-urllib3-1.26.12/debian/gbp.conf
--- python-urllib3-1.26.12/debian/gbp.conf	2022-08-25 11:04:08.000000000 +0200
+++ python-urllib3-1.26.12/debian/gbp.conf	2024-12-21 15:28:17.000000000 +0100
@@ -1,2 +1,2 @@
 [DEFAULT]
-debian-branch=debian/master
+debian-branch=debian/bookworm
diff -Nru python-urllib3-1.26.12/debian/patches/01_do-not-use-embedded-python-six.patch python-urllib3-1.26.12/debian/patches/01_do-not-use-embedded-python-six.patch
--- python-urllib3-1.26.12/debian/patches/01_do-not-use-embedded-python-six.patch	2022-09-22 23:14:14.000000000 +0200
+++ python-urllib3-1.26.12/debian/patches/01_do-not-use-embedded-python-six.patch	2024-12-21 15:28:17.000000000 +0100
@@ -26,11 +26,12 @@
  src/urllib3/util/response.py                     | 2 +-
  src/urllib3/util/retry.py                        | 2 +-
  src/urllib3/util/ssl_.py                         | 2 +-
+ src/urllib3/util/ssltransport.py                 | 2 +-
  src/urllib3/util/url.py                          | 2 +-
  test/__init__.py                                 | 2 +-
  test/test_collections.py                         | 2 +-
  test/test_compatibility.py                       | 2 +-
- test/test_connectionpool.py                      | 7 ++++---
+ test/test_connectionpool.py                      | 6 +++---
  test/test_fields.py                              | 2 +-
  test/test_filepost.py                            | 2 +-
  test/test_queue_monkeypatch.py                   | 2 +-
@@ -41,7 +42,7 @@
  test/with_dummyserver/test_connectionpool.py     | 4 ++--
  test/with_dummyserver/test_https.py              | 2 +-
  test/with_dummyserver/test_socketlevel.py        | 2 +-
- 35 files changed, 53 insertions(+), 50 deletions(-)
+ 36 files changed, 53 insertions(+), 51 deletions(-)
 
 diff --git a/dummyserver/handlers.py b/dummyserver/handlers.py
 index c90c2fc..f8bdf25 100644
@@ -339,6 +340,19 @@
  from .url import BRACELESS_IPV6_ADDRZ_RE, IPV4_RE
  
  SSLContext = None
+diff --git a/src/urllib3/util/ssltransport.py b/src/urllib3/util/ssltransport.py
+index 4a7105d..eaa2b60 100644
+--- a/src/urllib3/util/ssltransport.py
++++ b/src/urllib3/util/ssltransport.py
+@@ -3,7 +3,7 @@ import socket
+ import ssl
+ 
+ from ..exceptions import ProxySchemeUnsupported
+-from ..packages import six
++import six
+ 
+ SSL_BLOCKSIZE = 16384
+ 
 diff --git a/src/urllib3/util/url.py b/src/urllib3/util/url.py
 index b667c16..515d6fc 100644
 --- a/src/urllib3/util/url.py
@@ -392,7 +406,7 @@
  
  
 diff --git a/test/test_connectionpool.py b/test/test_connectionpool.py
-index 872d01c..3a9fb9d 100644
+index 872d01c..ad70c45 100644
 --- a/test/test_connectionpool.py
 +++ b/test/test_connectionpool.py
 @@ -7,6 +7,9 @@ from test import SHORT_TIMEOUT
@@ -405,14 +419,13 @@
  
  from dummyserver.server import DEFAULT_CA
  from urllib3._collections import HTTPHeaderDict
-@@ -26,9 +29,7 @@ from urllib3.exceptions import (
+@@ -26,9 +29,6 @@ from urllib3.exceptions import (
      SSLError,
      TimeoutError,
  )
 -from urllib3.packages.six.moves import http_client as httplib
 -from urllib3.packages.six.moves.http_client import HTTPException
 -from urllib3.packages.six.moves.queue import Empty
-+from urllib3.packages.ssl_match_hostname import CertificateError
  from urllib3.response import HTTPResponse
  from urllib3.util.ssl_match_hostname import CertificateError
  from urllib3.util.timeout import Timeout
diff -Nru python-urllib3-1.26.12/debian/patches/CVE-2023-43804.patch python-urllib3-1.26.12/debian/patches/CVE-2023-43804.patch
--- python-urllib3-1.26.12/debian/patches/CVE-2023-43804.patch	1970-01-01 01:00:00.000000000 +0100
+++ python-urllib3-1.26.12/debian/patches/CVE-2023-43804.patch	2024-12-21 15:28:17.000000000 +0100
@@ -0,0 +1,157 @@
+From: Seth Michael Larson <sethmichaellarson@gmail.com>
+Date: Mon, 2 Oct 2023 11:43:46 -0500
+Subject: Backport GHSA-v845-jxx5-vc9f
+
+Co-authored-by: Quentin Pradet <quentin.pradet@gmail.com>
+Co-authored-by: Illia Volochii <illia.volochii@gmail.com>
+Origin: https://github.com/urllib3/urllib3/commit/01220354d389cd05474713f8c982d05c9b17aafb
+Bug: https://github.com/urllib3/urllib3/security/advisories/GHSA-v845-jxx5-vc9f
+Bug: https://github.com/urllib3/urllib3/pull/3139
+Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2023-43804
+Bug-Debian: https://bugs.debian.org/1053626
+---
+ 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, 23 insertions(+), 9 deletions(-)
+
+diff --git a/src/urllib3/util/retry.py b/src/urllib3/util/retry.py
+index 4473a8e..8caad44 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 53f0935..7297aa5 100644
+--- a/test/test_retry.py
++++ b/test/test_retry.py
+@@ -293,12 +293,12 @@ class TestRetry(object):
+     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 4b3c9d8..30acfce 100644
+--- a/test/test_retry_deprecated.py
++++ b/test/test_retry_deprecated.py
+@@ -295,7 +295,7 @@ class TestRetry(object):
+     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 fa07a37..02a3811 100644
+--- a/test/with_dummyserver/test_poolmanager.py
++++ b/test/with_dummyserver/test_poolmanager.py
+@@ -141,7 +141,7 @@ class TestPoolManager(HTTPDummyServerTestCase):
+                 "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 @@ class TestPoolManager(HTTPDummyServerTestCase):
+             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 @@ class TestPoolManager(HTTPDummyServerTestCase):
+ 
+             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 @@ class TestPoolManager(HTTPDummyServerTestCase):
+                 "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 @@ class TestPoolManager(HTTPDummyServerTestCase):
+             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 @@ class TestPoolManager(HTTPDummyServerTestCase):
+                 "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 @@ class TestPoolManager(HTTPDummyServerTestCase):
+ 
+             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 @@ class TestPoolManager(HTTPDummyServerTestCase):
+             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:
diff -Nru python-urllib3-1.26.12/debian/patches/CVE-2023-45803.patch python-urllib3-1.26.12/debian/patches/CVE-2023-45803.patch
--- python-urllib3-1.26.12/debian/patches/CVE-2023-45803.patch	1970-01-01 01:00:00.000000000 +0100
+++ python-urllib3-1.26.12/debian/patches/CVE-2023-45803.patch	2024-12-21 15:28:17.000000000 +0100
@@ -0,0 +1,177 @@
+From: Illia Volochii <illia.volochii@gmail.com>
+Date: Tue, 17 Oct 2023 19:35:39 +0300
+Subject: Merge pull request from GHSA-g4mx-q9vg-27p4
+
+Origin: https://github.com/urllib3/urllib3/commit/b594c5ceaca38e1ac215f916538fb128e3526a36
+Bug: https://github.com/urllib3/urllib3/security/advisories/GHSA-g4mx-q9vg-27p4
+Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2023-45803
+Bug-Debian: https://bugs.debian.org/1054226
+---
+ dummyserver/handlers.py                      |  7 +++++++
+ src/urllib3/_collections.py                  | 18 ++++++++++++++++++
+ src/urllib3/connectionpool.py                |  5 +++++
+ src/urllib3/poolmanager.py                   |  7 +++++--
+ test/with_dummyserver/test_connectionpool.py | 11 +++++++++++
+ test/with_dummyserver/test_poolmanager.py    | 15 +++++++++++++++
+ 6 files changed, 61 insertions(+), 2 deletions(-)
+
+diff --git a/dummyserver/handlers.py b/dummyserver/handlers.py
+index f8bdf25..7d3e413 100644
+--- a/dummyserver/handlers.py
++++ b/dummyserver/handlers.py
+@@ -186,6 +186,8 @@ class TestingApp(RequestHandler):
+         status = request.params.get("status", "303 See Other")
+         if len(status) == 3:
+             status = "%s Redirect" % status.decode("latin-1")
++        elif isinstance(status, bytes):
++            status = status.decode("latin-1")
+ 
+         headers = [("Location", target)]
+         return Response(status=status, headers=headers)
+@@ -264,6 +266,11 @@ class TestingApp(RequestHandler):
+     def headers(self, request):
+         return Response(json.dumps(dict(request.headers)))
+ 
++    def headers_and_params(self, request):
++        return Response(
++            json.dumps({"headers": dict(request.headers), "params": request.params})
++        )
++
+     def successful_retry(self, request):
+         """Handler which will return an error and then success
+ 
+diff --git a/src/urllib3/_collections.py b/src/urllib3/_collections.py
+index 527c1fe..6bc6e2c 100644
+--- a/src/urllib3/_collections.py
++++ b/src/urllib3/_collections.py
+@@ -268,6 +268,24 @@ class HTTPHeaderDict(MutableMapping):
+         else:
+             return vals[1:]
+ 
++    def _prepare_for_method_change(self):
++        """
++        Remove content-specific header fields before changing the request
++        method to GET or HEAD according to RFC 9110, Section 15.4.
++        """
++        content_specific_headers = [
++            "Content-Encoding",
++            "Content-Language",
++            "Content-Location",
++            "Content-Type",
++            "Content-Length",
++            "Digest",
++            "Last-Modified",
++        ]
++        for header in content_specific_headers:
++            self.discard(header)
++        return self
++
+     # Backwards compatibility for httplib
+     getheaders = getlist
+     getallmatchingheaders = getlist
+diff --git a/src/urllib3/connectionpool.py b/src/urllib3/connectionpool.py
+index 2d50f3f..06aa8b8 100644
+--- a/src/urllib3/connectionpool.py
++++ b/src/urllib3/connectionpool.py
+@@ -12,6 +12,7 @@ from socket import timeout as SocketTimeout
+ import six
+ from six.moves import queue
+ 
++from ._collections import HTTPHeaderDict
+ from .connection import (
+     BaseSSLError,
+     BrokenPipeError,
+@@ -833,7 +834,11 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
+         redirect_location = redirect and response.get_redirect_location()
+         if redirect_location:
+             if response.status == 303:
++                # Change the method according to RFC 9110, Section 15.4.4.
+                 method = "GET"
++                # And lose the body not to transfer anything sensitive.
++                body = None
++                headers = HTTPHeaderDict(headers)._prepare_for_method_change()
+ 
+             try:
+                 retries = retries.increment(method, url, response=response, _pool=self)
+diff --git a/src/urllib3/poolmanager.py b/src/urllib3/poolmanager.py
+index ca305ec..87467ad 100644
+--- a/src/urllib3/poolmanager.py
++++ b/src/urllib3/poolmanager.py
+@@ -4,7 +4,7 @@ import collections
+ import functools
+ import logging
+ 
+-from ._collections import RecentlyUsedContainer
++from ._collections import HTTPHeaderDict, RecentlyUsedContainer
+ from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, port_by_scheme
+ from .exceptions import (
+     LocationValueError,
+@@ -382,9 +382,12 @@ class PoolManager(RequestMethods):
+         # Support relative URLs for redirecting.
+         redirect_location = urljoin(url, redirect_location)
+ 
+-        # RFC 7231, Section 6.4.4
+         if response.status == 303:
++            # Change the method according to RFC 9110, Section 15.4.4.
+             method = "GET"
++            # And lose the body not to transfer anything sensitive.
++            kw["body"] = None
++            kw["headers"] = HTTPHeaderDict(kw["headers"])._prepare_for_method_change()
+ 
+         retries = kw.get("retries")
+         if not isinstance(retries, Retry):
+diff --git a/test/with_dummyserver/test_connectionpool.py b/test/with_dummyserver/test_connectionpool.py
+index 2177c24..7fc0787 100644
+--- a/test/with_dummyserver/test_connectionpool.py
++++ b/test/with_dummyserver/test_connectionpool.py
+@@ -411,6 +411,17 @@ class TestConnectionPool(HTTPDummyServerTestCase):
+             assert r.status == 200
+             assert r.data == b"Dummy server!"
+ 
++    def test_303_redirect_makes_request_lose_body(self):
++        with HTTPConnectionPool(self.host, self.port) as pool:
++            response = pool.request(
++                "POST",
++                "/redirect",
++                fields={"target": "/headers_and_params", "status": "303 See Other"},
++            )
++        data = json.loads(response.data)
++        assert data["params"] == {}
++        assert "Content-Type" not in HTTPHeaderDict(data["headers"])
++
+     def test_bad_connect(self):
+         with HTTPConnectionPool("badhost.invalid", self.port) as pool:
+             with pytest.raises(MaxRetryError) as e:
+diff --git a/test/with_dummyserver/test_poolmanager.py b/test/with_dummyserver/test_poolmanager.py
+index 02a3811..509daf2 100644
+--- a/test/with_dummyserver/test_poolmanager.py
++++ b/test/with_dummyserver/test_poolmanager.py
+@@ -5,6 +5,7 @@ import pytest
+ 
+ from dummyserver.server import HAS_IPV6
+ from dummyserver.testcase import HTTPDummyServerTestCase, IPv6HTTPDummyServerTestCase
++from urllib3._collections import HTTPHeaderDict
+ from urllib3.connectionpool import port_by_scheme
+ from urllib3.exceptions import MaxRetryError, URLSchemeUnknown
+ from urllib3.poolmanager import PoolManager
+@@ -236,6 +237,20 @@ class TestPoolManager(HTTPDummyServerTestCase):
+             assert r._pool.num_connections == 1
+             assert len(http.pools) == 1
+ 
++    def test_303_redirect_makes_request_lose_body(self):
++        with PoolManager() as http:
++            response = http.request(
++                "POST",
++                "%s/redirect" % self.base_url,
++                fields={
++                    "target": "%s/headers_and_params" % self.base_url,
++                    "status": "303 See Other",
++                },
++            )
++        data = json.loads(response.data)
++        assert data["params"] == {}
++        assert "Content-Type" not in HTTPHeaderDict(data["headers"])
++
+     def test_unknown_scheme(self):
+         with PoolManager() as http:
+             unknown_scheme = "unknown"
diff -Nru python-urllib3-1.26.12/debian/patches/CVE-2024-37891.patch python-urllib3-1.26.12/debian/patches/CVE-2024-37891.patch
--- python-urllib3-1.26.12/debian/patches/CVE-2024-37891.patch	1970-01-01 01:00:00.000000000 +0100
+++ python-urllib3-1.26.12/debian/patches/CVE-2024-37891.patch	2024-12-21 15:28:17.000000000 +0100
@@ -0,0 +1,164 @@
+From: Quentin Pradet <quentin.pradet@gmail.com>
+Date: Mon, 17 Jun 2024 11:09:06 +0400
+Subject: Merge pull request from GHSA-34jh-p97f-mpxf
+
+Strip Proxy-Authorization header on redirects
+
+Origin: https://github.com/urllib3/urllib3/commit/40b6d1605814dd1db0a46e202d6e56f2e4c9a468
+Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2024-37891
+Bug-Debian: https://bugs.debian.org/1074149
+---
+ src/urllib3/util/retry.py                 |  4 +++-
+ test/test_retry.py                        |  6 +++++-
+ test/test_retry_deprecated.py             |  6 +++++-
+ test/with_dummyserver/test_poolmanager.py | 26 +++++++++++++++++++++++---
+ 4 files changed, 36 insertions(+), 6 deletions(-)
+
+diff --git a/src/urllib3/util/retry.py b/src/urllib3/util/retry.py
+index 8caad44..e00bf4b 100644
+--- a/src/urllib3/util/retry.py
++++ b/src/urllib3/util/retry.py
+@@ -235,7 +235,9 @@ 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(["Cookie", "Authorization"])
++    DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(
++        ["Cookie", "Authorization", "Proxy-Authorization"]
++    )
+ 
+     #: Maximum backoff time.
+     DEFAULT_BACKOFF_MAX = 120
+diff --git a/test/test_retry.py b/test/test_retry.py
+index 7297aa5..7468322 100644
+--- a/test/test_retry.py
++++ b/test/test_retry.py
+@@ -293,7 +293,11 @@ class TestRetry(object):
+     def test_retry_default_remove_headers_on_redirect(self):
+         retry = Retry()
+ 
+-        assert retry.remove_headers_on_redirect == {"authorization", "cookie"}
++        assert retry.remove_headers_on_redirect == {
++            "authorization",
++            "proxy-authorization",
++            "cookie",
++        }
+ 
+     def test_retry_set_remove_headers_on_redirect(self):
+         retry = Retry(remove_headers_on_redirect=["X-API-Secret"])
+diff --git a/test/test_retry_deprecated.py b/test/test_retry_deprecated.py
+index 30acfce..f10aff5 100644
+--- a/test/test_retry_deprecated.py
++++ b/test/test_retry_deprecated.py
+@@ -295,7 +295,11 @@ class TestRetry(object):
+     def test_retry_default_remove_headers_on_redirect(self):
+         retry = Retry()
+ 
+-        assert retry.remove_headers_on_redirect == {"authorization", "cookie"}
++        assert retry.remove_headers_on_redirect == {
++            "authorization",
++            "proxy-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 509daf2..02e3de5 100644
+--- a/test/with_dummyserver/test_poolmanager.py
++++ b/test/with_dummyserver/test_poolmanager.py
+@@ -142,7 +142,11 @@ class TestPoolManager(HTTPDummyServerTestCase):
+                 "GET",
+                 "%s/redirect" % self.base_url,
+                 fields={"target": "%s/headers" % self.base_url_alt},
+-                headers={"Authorization": "foo", "Cookie": "foo=bar"},
++                headers={
++                    "Authorization": "foo",
++                    "Proxy-Authorization": "bar",
++                    "Cookie": "foo=bar",
++                },
+             )
+ 
+             assert r.status == 200
+@@ -150,13 +154,18 @@ class TestPoolManager(HTTPDummyServerTestCase):
+             data = json.loads(r.data.decode("utf-8"))
+ 
+             assert "Authorization" not in data
++            assert "Proxy-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", "cookie": "foo=bar"},
++                headers={
++                    "authorization": "foo",
++                    "proxy-authorization": "baz",
++                    "cookie": "foo=bar",
++                },
+             )
+ 
+             assert r.status == 200
+@@ -165,6 +174,8 @@ class TestPoolManager(HTTPDummyServerTestCase):
+ 
+             assert "authorization" not in data
+             assert "Authorization" not in data
++            assert "proxy-authorization" not in data
++            assert "Proxy-Authorization" not in data
+             assert "cookie" not in data
+             assert "Cookie" not in data
+ 
+@@ -174,7 +185,11 @@ class TestPoolManager(HTTPDummyServerTestCase):
+                 "GET",
+                 "%s/redirect" % self.base_url,
+                 fields={"target": "%s/headers" % self.base_url_alt},
+-                headers={"Authorization": "foo", "Cookie": "foo=bar"},
++                headers={
++                    "Authorization": "foo",
++                    "Proxy-Authorization": "bar",
++                    "Cookie": "foo=bar",
++                },
+                 retries=Retry(remove_headers_on_redirect=[]),
+             )
+ 
+@@ -183,6 +198,7 @@ class TestPoolManager(HTTPDummyServerTestCase):
+             data = json.loads(r.data.decode("utf-8"))
+ 
+             assert data["Authorization"] == "foo"
++            assert data["Proxy-Authorization"] == "bar"
+             assert data["Cookie"] == "foo=bar"
+ 
+     def test_redirect_cross_host_set_removed_headers(self):
+@@ -194,6 +210,7 @@ class TestPoolManager(HTTPDummyServerTestCase):
+                 headers={
+                     "X-API-Secret": "foo",
+                     "Authorization": "bar",
++                    "Proxy-Authorization": "baz",
+                     "Cookie": "foo=bar",
+                 },
+                 retries=Retry(remove_headers_on_redirect=["X-API-Secret"]),
+@@ -205,6 +222,7 @@ class TestPoolManager(HTTPDummyServerTestCase):
+ 
+             assert "X-API-Secret" not in data
+             assert data["Authorization"] == "bar"
++            assert data["Proxy-Authorization"] == "baz"
+             assert data["Cookie"] == "foo=bar"
+ 
+             r = http.request(
+@@ -213,6 +231,7 @@ class TestPoolManager(HTTPDummyServerTestCase):
+                 fields={"target": "%s/headers" % self.base_url_alt},
+                 headers={
+                     "x-api-secret": "foo",
++                    "proxy-authorization": "baz",
+                     "authorization": "bar",
+                     "cookie": "foo=bar",
+                 },
+@@ -226,6 +245,7 @@ class TestPoolManager(HTTPDummyServerTestCase):
+             assert "x-api-secret" not in data
+             assert "X-API-Secret" not in data
+             assert data["Authorization"] == "bar"
++            assert data["Proxy-Authorization"] == "baz"
+             assert data["Cookie"] == "foo=bar"
+ 
+     def test_redirect_without_preload_releases_connection(self):
diff -Nru python-urllib3-1.26.12/debian/patches/series python-urllib3-1.26.12/debian/patches/series
--- python-urllib3-1.26.12/debian/patches/series	2022-08-25 11:04:08.000000000 +0200
+++ python-urllib3-1.26.12/debian/patches/series	2024-12-21 15:28:17.000000000 +0100
@@ -1,2 +1,5 @@
 01_do-not-use-embedded-python-six.patch
 02_require-cert-verification.patch
+CVE-2023-43804.patch
+CVE-2023-45803.patch
+CVE-2024-37891.patch
diff -Nru python-urllib3-1.26.12/debian/salsa-ci.yml python-urllib3-1.26.12/debian/salsa-ci.yml
--- python-urllib3-1.26.12/debian/salsa-ci.yml	2022-08-25 11:04:08.000000000 +0200
+++ python-urllib3-1.26.12/debian/salsa-ci.yml	2024-12-21 15:28:17.000000000 +0100
@@ -1,3 +1,8 @@
 ---
 include:
   - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.yml
+
+variables:
+  RELEASE: 'bookworm'
+  SALSA_CI_DISABLE_REPROTEST: 1
+  SALSA_CI_DISABLE_LINTIAN: 1

Attachment: signature.asc
Description: PGP signature


--- End Message ---
--- Begin Message ---
Version: 12.9
This update has been released as part of 12.9. Thank you for your contribution.

--- End Message ---

Reply to: