* [OE-core][scarthgap][PATCH] python3-urllib3: fix CVE-2026-44431
@ 2026-06-01 18:11 Sudhir Dumbhare -X (sudumbha - E INFOCHIPS PRIVATE LIMITED at Cisco)
2026-06-12 10:24 ` Jeremy Rosen
0 siblings, 1 reply; 4+ messages in thread
From: Sudhir Dumbhare -X (sudumbha - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-06-01 18:11 UTC (permalink / raw)
To: openembedded-core
From: Sudhir Dumbhare <sudumbha@cisco.com>
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 <sudumbha@cisco.com>
---
.../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 <illia.volochii@gmail.com>
+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 <copilot@github.com>
+
+---------
+
+Co-authored-by: Copilot <copilot@github.com>
+(cherry picked from commit 5ec0de499b9166ca71c65ab04f2a7e4eb0d66fcc)
+Signed-off-by: Sudhir Dumbhare <sudumbha@cisco.com>
+---
+ 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} += "\
--
2.35.6
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [OE-core][scarthgap][PATCH] python3-urllib3: fix CVE-2026-44431
2026-06-01 18:11 [OE-core][scarthgap][PATCH] python3-urllib3: fix CVE-2026-44431 Sudhir Dumbhare -X (sudumbha - E INFOCHIPS PRIVATE LIMITED at Cisco)
@ 2026-06-12 10:24 ` Jeremy Rosen
2026-07-06 17:10 ` Yoann Congal
0 siblings, 1 reply; 4+ messages in thread
From: Jeremy Rosen @ 2026-06-12 10:24 UTC (permalink / raw)
To: sudumbha, openembedded-core
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 <sudumbha@cisco.com>
>
> 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 <sudumbha@cisco.com>
> ---
> .../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 <illia.volochii@gmail.com>
> +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 <copilot@github.com>
> +
> +---------
> +
> +Co-authored-by: Copilot <copilot@github.com>
> +(cherry picked from commit 5ec0de499b9166ca71c65ab04f2a7e4eb0d66fcc)
> +Signed-off-by: Sudhir Dumbhare <sudumbha@cisco.com>
> +---
> + 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} += "\
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [OE-core][scarthgap][PATCH] python3-urllib3: fix CVE-2026-44431
2026-06-12 10:24 ` Jeremy Rosen
@ 2026-07-06 17:10 ` Yoann Congal
2026-07-08 11:53 ` [scarthgap][PATCH] " Sudhir Dumbhare
0 siblings, 1 reply; 4+ messages in thread
From: Yoann Congal @ 2026-07-06 17:10 UTC (permalink / raw)
To: jeremy.rosen, sudumbha, openembedded-core
On Fri Jun 12, 2026 at 12:24 PM CEST, Jérémy Rosen via lists.openembedded.org wrote:
> 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
Hello Sudhir,
Gentle ping for this patch.
Regards,
>
> On Mon Jun 1, 2026 at 8:11 PM CEST, Sudhir Dumbhare via lists.openembedded.org wrote:
>> From: Sudhir Dumbhare <sudumbha@cisco.com>
>>
>> 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 <sudumbha@cisco.com>
>> ---
>> .../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
>>
--
Yoann Congal
Smile ECS
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [scarthgap][PATCH] python3-urllib3: fix CVE-2026-44431
2026-07-06 17:10 ` Yoann Congal
@ 2026-07-08 11:53 ` Sudhir Dumbhare
0 siblings, 0 replies; 4+ messages in thread
From: Sudhir Dumbhare @ 2026-07-08 11:53 UTC (permalink / raw)
To: openembedded-core
[-- Attachment #1: Type: text/plain, Size: 274 bytes --]
Hello Yoann and Jérémy,
Thank you for your review and g entle reminder.
I have sent the patch for wrynose here;
[wrynose][PATCH] python3-urllib3: Fix CVE-2026-44431 ( https://lists.openembedded.org/g/openembedded-core/message/240334 )
Thanks and Regards,
Sudhir
[-- Attachment #2: Type: text/html, Size: 1135 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-07-08 11:53 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-01 18:11 [OE-core][scarthgap][PATCH] python3-urllib3: fix CVE-2026-44431 Sudhir Dumbhare -X (sudumbha - E INFOCHIPS PRIVATE LIMITED at Cisco)
2026-06-12 10:24 ` Jeremy Rosen
2026-07-06 17:10 ` Yoann Congal
2026-07-08 11:53 ` [scarthgap][PATCH] " Sudhir Dumbhare
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox