Hello Sudhir

This CVE also affects wrynose and I could not find any submission for
wrynose

please submit for wrynose and once it is affected ping here

Thanks a lot 
Jérémy

On Mon Jun 1, 2026 at 8:11 PM CEST, Sudhir Dumbhare via lists.openembedded.org 
wrote:
> From: Sudhir Dumbhare <[email protected]>
>
> Applies the upstream fix [1] referenced in [2] and addresses the
> sensitive-header redirect handling issue in proxied low-level urllib3 
> requests.
>
> [1] 
> https://github.com/urllib3/urllib3/commit/5ec0de499b9166ca71c65ab04f2a7e4eb0d66fcc
> [2] https://ubuntu.com/security/CVE-2026-44431
>
> References:
> https://nvd.nist.gov/vuln/detail/CVE-2026-44431
>
> Signed-off-by: Sudhir Dumbhare <[email protected]>
> ---
>  .../python3-urllib3/CVE-2026-44431.patch      | 163 ++++++++++++++++++
>  .../python/python3-urllib3_2.2.2.bb           |   1 +
>  2 files changed, 164 insertions(+)
>  create mode 100644 
> meta/recipes-devtools/python/python3-urllib3/CVE-2026-44431.patch
>
> diff --git 
> a/meta/recipes-devtools/python/python3-urllib3/CVE-2026-44431.patch 
> b/meta/recipes-devtools/python/python3-urllib3/CVE-2026-44431.patch
> new file mode 100644
> index 0000000000..042b46f47a
> --- /dev/null
> +++ b/meta/recipes-devtools/python/python3-urllib3/CVE-2026-44431.patch
> @@ -0,0 +1,163 @@
> +From d5517b0ab50030a8f389757b3ba648633c504cbc Mon Sep 17 00:00:00 2001
> +From: Illia Volochii <[email protected]>
> +Date: Thu, 7 May 2026 18:40:31 +0300
> +Subject: [PATCH] Merge commit from fork
> +
> +* Remove sensitive headers in proxy pools too
> +
> +* Add a changelog entry
> +
> +* Check retries history in tests
> +
> +CVE: CVE-2026-44431
> +Upstream-Status: Backport 
> [https://github.com/urllib3/urllib3/commit/5ec0de499b9166ca71c65ab04f2a7e4eb0d66fcc]
> +
> +Co-authored-by: Copilot <[email protected]>
> +
> +---------
> +
> +Co-authored-by: Copilot <[email protected]>
> +(cherry picked from commit 5ec0de499b9166ca71c65ab04f2a7e4eb0d66fcc)
> +Signed-off-by: Sudhir Dumbhare <[email protected]>
> +---
> + changelog/GHSA-qccp-gfcp-xxvc.bugfix.rst      |  3 +
> + dummyserver/asgi_proxy.py                     |  1 +
> + src/urllib3/connectionpool.py                 | 12 ++++
> + .../test_proxy_poolmanager.py                 | 72 +++++++++++++++++++
> + 4 files changed, 88 insertions(+)
> + create mode 100644 changelog/GHSA-qccp-gfcp-xxvc.bugfix.rst
> +
> +diff --git a/changelog/GHSA-qccp-gfcp-xxvc.bugfix.rst 
> b/changelog/GHSA-qccp-gfcp-xxvc.bugfix.rst
> +new file mode 100644
> +index 00000000..bac765ea
> +--- /dev/null
> ++++ b/changelog/GHSA-qccp-gfcp-xxvc.bugfix.rst
> +@@ -0,0 +1,3 @@
> ++Fixed HTTP pools created using ``ProxyManager.connection_from_url`` to strip
> ++sensitive headers specified in ``Retry.remove_headers_on_redirect`` when
> ++redirecting to a different host.
> +diff --git a/dummyserver/asgi_proxy.py b/dummyserver/asgi_proxy.py
> +index 107c5e0a..094807cd 100755
> +--- a/dummyserver/asgi_proxy.py
> ++++ b/dummyserver/asgi_proxy.py
> +@@ -52,6 +52,7 @@ class ProxyApp:
> +             client_response = await client.request(
> +                 method=scope["method"],
> +                 url=scope["path"],
> ++                params=scope["query_string"].decode(),
> +                 headers=list(scope["headers"]),
> +                 content=await _read_body(receive),
> +             )
> +diff --git a/src/urllib3/connectionpool.py b/src/urllib3/connectionpool.py
> +index a2c3cf60..f64ee2f8 100644
> +--- a/src/urllib3/connectionpool.py
> ++++ b/src/urllib3/connectionpool.py
> +@@ -898,6 +898,18 @@ class HTTPConnectionPool(ConnectionPool, 
> RequestMethods):
> +                 body = None
> +                 headers = 
> HTTPHeaderDict(headers)._prepare_for_method_change()
> + 
> ++            # Strip headers marked as unsafe to forward to the redirected 
> location.
> ++            # Check remove_headers_on_redirect to avoid a potential network 
> call within
> ++            # self.is_same_host() which may use socket.gethostbyname() in 
> the future.
> ++            if retries.remove_headers_on_redirect and not self.is_same_host(
> ++                redirect_location
> ++            ):
> ++                new_headers = headers.copy()  # type: ignore[union-attr]
> ++                for header in headers:
> ++                    if header.lower() in retries.remove_headers_on_redirect:
> ++                        new_headers.pop(header, None)
> ++                headers = new_headers
> ++
> +             try:
> +                 retries = retries.increment(method, url, response=response, 
> _pool=self)
> +             except MaxRetryError:
> +diff --git a/test/with_dummyserver/test_proxy_poolmanager.py 
> b/test/with_dummyserver/test_proxy_poolmanager.py
> +index 397181a9..a0b11726 100644
> +--- a/test/with_dummyserver/test_proxy_poolmanager.py
> ++++ b/test/with_dummyserver/test_proxy_poolmanager.py
> +@@ -37,6 +37,7 @@ from urllib3.exceptions import (
> +     SSLError,
> + )
> + from urllib3.poolmanager import ProxyManager, proxy_from_url
> ++from urllib3.util.retry import RequestHistory
> + from urllib3.util.ssl_ import create_urllib3_context
> + from urllib3.util.timeout import Timeout
> + 
> +@@ -299,6 +300,77 @@ class TestHTTPProxyManager(HypercornDummyProxyTestCase):
> +             assert r._pool is not None
> +             assert r._pool.host != self.http_host_alt
> + 
> ++    _sensitive_headers = {
> ++        "Authorization": "foo",
> ++        "Proxy-Authorization": "bar",
> ++        "Cookie": "foo=bar",
> ++    }
> ++
> ++    @pytest.mark.parametrize(
> ++        "sensitive_headers",
> ++        (_sensitive_headers, {k.lower(): v for k, v in 
> _sensitive_headers.items()}),
> ++        ids=("capitalized", "lowercase"),
> ++    )
> ++    def test_cross_host_redirect_remove_headers_via_proxy_manager(
> ++        self, sensitive_headers: dict[str, str]
> ++    ) -> None:
> ++        headers_url = f"{self.http_url_alt}/headers"
> ++        initial_url = f"{self.http_url}/redirect?target={headers_url}"
> ++        with proxy_from_url(self.proxy_url) as proxy_mgr:
> ++            r = proxy_mgr.request(
> ++                "GET", initial_url, headers=sensitive_headers, retries=1
> ++            )
> ++            assert r.status == 200
> ++            assert r.retries is not None
> ++            assert r.retries.history == (
> ++                RequestHistory(
> ++                    method="GET",
> ++                    url=initial_url,
> ++                    error=None,
> ++                    status=303,
> ++                    redirect_location=headers_url,
> ++                ),
> ++            )
> ++            data = r.json()
> ++            for header in sensitive_headers:
> ++                assert header not in data
> ++
> ++    @pytest.mark.parametrize(
> ++        "sensitive_headers",
> ++        (_sensitive_headers, {k.lower(): v for k, v in 
> _sensitive_headers.items()}),
> ++        ids=("capitalized", "lowercase"),
> ++    )
> ++    def test_cross_host_redirect_remove_headers_via_pool(
> ++        self, sensitive_headers: dict[str, str]
> ++    ) -> None:
> ++        headers_url = f"{self.http_url_alt}/headers"
> ++        initial_url = f"{self.http_url}/redirect?target={headers_url}"
> ++        with proxy_from_url(self.proxy_url) as proxy_mgr:
> ++            pool = proxy_mgr.connection_from_url(self.http_url)
> ++            r = pool.urlopen(
> ++                "GET",
> ++                initial_url,
> ++                headers=sensitive_headers,
> ++                retries=1,
> ++                redirect=True,
> ++                assert_same_host=False,
> ++                preload_content=True,
> ++            )
> ++            assert r.status == 200
> ++            assert r.retries is not None
> ++            assert r.retries.history == (
> ++                RequestHistory(
> ++                    method="GET",
> ++                    url=initial_url,
> ++                    error=None,
> ++                    status=303,
> ++                    redirect_location=headers_url,
> ++                ),
> ++            )
> ++            data = r.json()
> ++            for header in sensitive_headers:
> ++                assert header not in data
> ++
> +     def test_cross_protocol_redirect(self) -> None:
> +         with proxy_from_url(self.proxy_url, ca_certs=DEFAULT_CA) as http:
> +             cross_protocol_location = f"{self.https_url}/echo?a=b"
> diff --git a/meta/recipes-devtools/python/python3-urllib3_2.2.2.bb 
> b/meta/recipes-devtools/python/python3-urllib3_2.2.2.bb
> index f6ac8f89ca..b77dd5297d 100644
> --- a/meta/recipes-devtools/python/python3-urllib3_2.2.2.bb
> +++ b/meta/recipes-devtools/python/python3-urllib3_2.2.2.bb
> @@ -12,6 +12,7 @@ SRC_URI += " \
>      file://CVE-2025-66418.patch \
>      file://CVE-2025-66471.patch \
>      file://CVE-2026-21441.patch \
> +    file://CVE-2026-44431.patch \
>  "
>  
>  RDEPENDS:${PN} += "\

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#238599): 
https://lists.openembedded.org/g/openembedded-core/message/238599
Mute This Topic: https://lists.openembedded.org/mt/119597979/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to