From 8f838e10065b91cff4f40ca5bf4ed61d88425f3a Mon Sep 17 00:00:00 2001 From: Darsh Kelaiya Date: Mon, 28 Sep 2026 10:43:19 -0700 Subject: [PATCH] python3-aiohttp: fix CVE-2026-54275 This patch applies the reviewed upstream fix shown in [1]. The advisory identifying the fix is referenced in [2]. [1] https://github.com/aio-libs/aiohttp/commit/0ca2b6c28a25726527a8b60f25960262a91ed0e0 [2] https://nvd.nist.gov/vuln/detail/CVE-2026-54275 Signed-off-by: Darsh Kelaiya Signed-off-by: Anuj Mittal --- .../python3-aiohttp/CVE-2026-54275.patch | 124 ++++++++++++++++++ .../python/python3-aiohttp_3.9.5.bb | 1 + 2 files changed, 125 insertions(+) create mode 100644 meta-python/recipes-devtools/python/python3-aiohttp/CVE-2026-54275.patch diff --git a/meta-python/recipes-devtools/python/python3-aiohttp/CVE-2026-54275.patch b/meta-python/recipes-devtools/python/python3-aiohttp/CVE-2026-54275.patch new file mode 100644 index 0000000000..21528ccb07 --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-aiohttp/CVE-2026-54275.patch @@ -0,0 +1,124 @@ +From 87daca6e11c2123c04d737bde7ddef35a154b272 Mon Sep 17 00:00:00 2001 +From: "J. Nick Koston" +Date: Sun, 7 Jun 2026 00:30:30 -0500 +Subject: [PATCH] [PR #12835/1e94b3e8 backport][3.14] Tls server hostname pool + key (#12847) + +CVE: CVE-2026-54275 +Upstream-Status: Backport [https://github.com/aio-libs/aiohttp/commit/0ca2b6c28a25726527a8b60f25960262a91ed0e0] + +Backport Changes: +- Upstream uses a NamedTuple ConnectionKey with PEP 604 union + annotations; aiohttp 3.9.5 uses an attr.s class, so server_hostname + is added with the equivalent Optional[str] annotation and included + in its constructor. +- aiohttp 3.9.5 does not define the newer AiohttpServer or + _RequestMaker test aliases, so their fixture annotations are + omitted. The request-key test is synchronous because this branch's + make_request fixture returns ClientRequest directly. + +(cherry picked from commit 0ca2b6c28a25726527a8b60f25960262a91ed0e0) +Signed-off-by: Darsh Kelaiya +--- + CHANGES/12835.bugfix.rst | 1 + + aiohttp/client_reqrep.py | 2 ++ + tests/test_client_functional.py | 29 +++++++++++++++++++++++++++++ + tests/test_client_request.py | 14 ++++++++++++++ + 4 files changed, 46 insertions(+) + create mode 100644 CHANGES/12835.bugfix.rst + +diff --git a/CHANGES/12835.bugfix.rst b/CHANGES/12835.bugfix.rst +new file mode 100644 +index 000000000..84a8ae006 +--- /dev/null ++++ b/CHANGES/12835.bugfix.rst +@@ -0,0 +1 @@ ++Included the per-request ``server_hostname`` override in the :class:`~aiohttp.TCPConnector` connection pool key, so a pooled TLS connection is no longer reused for a request that sets ``server_hostname`` to a different value -- by :user:`bdraco`. +diff --git a/aiohttp/client_reqrep.py b/aiohttp/client_reqrep.py +index afe719da1..9abfc79de 100644 +--- a/aiohttp/client_reqrep.py ++++ b/aiohttp/client_reqrep.py +@@ -220,6 +220,7 @@ class ConnectionKey: + proxy: Optional[URL] + proxy_auth: Optional[BasicAuth] + proxy_headers_hash: Optional[int] # hash(CIMultiDict) ++ server_hostname: Optional[str] = None + + + def _is_expected_content_type( +@@ -377,6 +378,7 @@ class ClientRequest: + self.proxy, + self.proxy_auth, + h, ++ self.server_hostname, + ) + + @property +diff --git a/tests/test_client_functional.py b/tests/test_client_functional.py +index 2c531d7d3..40c551ffa 100644 +--- a/tests/test_client_functional.py ++++ b/tests/test_client_functional.py +@@ -462,6 +462,35 @@ async def test_ssl_client( + assert txt == "Test message" + + ++async def test_server_hostname_override_not_reused(aiohttp_server) -> None: ++ """A pooled TLS connection must not be reused for a different server_hostname.""" ++ trustme = pytest.importorskip("trustme") ++ ++ ca = trustme.CA() ++ cert = ca.issue_cert("first.example") ++ server_ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) ++ cert.configure_cert(server_ctx) ++ client_ctx = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH) ++ ca.configure_trust(client_ctx) ++ ++ async def handler(request: web.Request) -> web.Response: ++ return web.Response(text="ok") ++ ++ app = web.Application() ++ app.router.add_route("GET", "/", handler) ++ server = await aiohttp_server(app, ssl=server_ctx) ++ url = server.make_url("/") ++ ++ connector = aiohttp.TCPConnector(ssl=client_ctx, limit=1, limit_per_host=1) ++ async with aiohttp.ClientSession(connector=connector) as session: ++ async with session.get(url, server_hostname="first.example") as resp: ++ assert resp.status == 200 ++ await resp.read() ++ ++ with pytest.raises(aiohttp.ClientConnectorCertificateError): ++ await session.get(url, server_hostname="second.example") ++ ++ + async def test_tcp_connector_fingerprint_ok( + aiohttp_server, + aiohttp_client, +diff --git a/tests/test_client_request.py b/tests/test_client_request.py +index 6084f6854..0ef6e92d6 100644 +--- a/tests/test_client_request.py ++++ b/tests/test_client_request.py +@@ -1326,6 +1326,20 @@ def test_insecure_fingerprint_sha1(loop) -> None: + Fingerprint(hashlib.sha1(b"foo").digest()) + + ++def test_connection_key_includes_server_hostname(make_request) -> None: ++ """A server_hostname override must be part of the connection reuse key.""" ++ url = URL("https://127.0.0.1:8443/") ++ none_req = make_request("GET", url) ++ first = make_request("GET", url, server_hostname="first.example") ++ first_again = make_request("GET", url, server_hostname="first.example") ++ second = make_request("GET", url, server_hostname="second.example") ++ ++ assert first.connection_key.server_hostname == "first.example" ++ assert first.connection_key != none_req.connection_key ++ assert first.connection_key != second.connection_key ++ assert first.connection_key == first_again.connection_key ++ ++ + def test_loose_cookies_types(loop) -> None: + req = ClientRequest("get", URL("http://python.org"), loop=loop) + morsel = Morsel() +-- +2.35.6 + diff --git a/meta-python/recipes-devtools/python/python3-aiohttp_3.9.5.bb b/meta-python/recipes-devtools/python/python3-aiohttp_3.9.5.bb index 5710e38943..42402f799b 100644 --- a/meta-python/recipes-devtools/python/python3-aiohttp_3.9.5.bb +++ b/meta-python/recipes-devtools/python/python3-aiohttp_3.9.5.bb @@ -30,6 +30,7 @@ SRC_URI += "file://CVE-2024-52304.patch \ file://CVE-2026-47265.patch \ file://CVE-2026-50269.patch \ file://CVE-2026-54274.patch \ + file://CVE-2026-54275.patch \ " CVE_STATUS[CVE-2026-34515] = "not-applicable-platform: Vulnerability only affects applications running on Windows"