diff --git a/CVE-2024-52303.patch b/CVE-2024-52303.patch new file mode 100644 index 0000000000000000000000000000000000000000..5ef1a963f25036ff9f2e3d1729cea2edc1df573f --- /dev/null +++ b/CVE-2024-52303.patch @@ -0,0 +1,105 @@ +commit bc15db61615079d1b6327ba42c682f758fa96936 +Author: J. Nick Koston +Date: Wed Nov 13 08:44:23 2024 -0600 + + [PR #9852/249855a backport][3.10] Fix system routes polluting the middleware cache (#9855) + +diff --git a/CHANGES/9852.bugfix.rst b/CHANGES/9852.bugfix.rst +new file mode 100644 +index 00000000..b459d084 +--- /dev/null ++++ b/CHANGES/9852.bugfix.rst +@@ -0,0 +1 @@ ++Fixed system routes polluting the middleware cache -- by :user:`bdraco`. +diff --git a/aiohttp/web_app.py b/aiohttp/web_app.py +index 78b1a67b..81a84833 100644 +--- a/aiohttp/web_app.py ++++ b/aiohttp/web_app.py +@@ -54,6 +54,7 @@ from .web_urldispatcher import ( + MaskDomain, + MatchedSubAppResource, + PrefixedSubAppResource, ++ SystemRoute, + UrlDispatcher, + ) + +@@ -79,7 +80,6 @@ _U = TypeVar("_U") + _Resource = TypeVar("_Resource", bound=AbstractResource) + + +-@lru_cache(None) + def _build_middlewares( + handler: Handler, apps: Tuple["Application", ...] + ) -> Callable[[Request], Awaitable[StreamResponse]]: +@@ -90,6 +90,9 @@ def _build_middlewares( + return handler + + ++_cached_build_middleware = lru_cache(maxsize=1024)(_build_middlewares) ++ ++ + class Application(MutableMapping[Union[str, AppKey[Any]], Any]): + ATTRS = frozenset( + [ +@@ -544,8 +547,13 @@ class Application(MutableMapping[Union[str, AppKey[Any]], Any]): + handler = match_info.handler + + if self._run_middlewares: +- if not self._has_legacy_middlewares: +- handler = _build_middlewares(handler, match_info.apps) ++ # If its a SystemRoute, don't cache building the middlewares since ++ # they are constructed for every MatchInfoError as a new handler ++ # is made each time. ++ if not self._has_legacy_middlewares and not isinstance( ++ match_info.route, SystemRoute ++ ): ++ handler = _cached_build_middleware(handler, match_info.apps) + else: + for app in match_info.apps[::-1]: + for m, new_style in app._middlewares_handlers: # type: ignore[union-attr] +diff --git a/tests/test_web_middleware.py b/tests/test_web_middleware.py +index 9c4462be..13acc589 100644 +--- a/tests/test_web_middleware.py ++++ b/tests/test_web_middleware.py +@@ -1,10 +1,11 @@ + import re +-from typing import Any ++from typing import Any, NoReturn + + import pytest + from yarl import URL + +-from aiohttp import web ++from aiohttp import web, web_app ++from aiohttp.pytest_plugin import AiohttpClient + from aiohttp.typedefs import Handler + + +@@ -520,3 +521,27 @@ async def test_new_style_middleware_method(loop, aiohttp_client) -> None: + assert 201 == resp.status + txt = await resp.text() + assert "OK[new style middleware]" == txt ++ ++ ++async def test_middleware_does_not_leak(aiohttp_client: AiohttpClient) -> None: ++ async def any_handler(request: web.Request) -> NoReturn: ++ assert False ++ ++ class Middleware: ++ @web.middleware ++ async def call( ++ self, request: web.Request, handler: Handler ++ ) -> web.StreamResponse: ++ return await handler(request) ++ ++ app = web.Application() ++ app.router.add_route("POST", "/any", any_handler) ++ app.middlewares.append(Middleware().call) ++ ++ client = await aiohttp_client(app) ++ ++ web_app._cached_build_middleware.cache_clear() ++ for _ in range(10): ++ resp = await client.get("/any") ++ assert resp.status == 405 ++ assert web_app._cached_build_middleware.cache_info().currsize < 10 diff --git a/python-aiohttp.spec b/python-aiohttp.spec index 145006b53bbf236be2f4a0129ad5e523413fb6c0..31dfc95ab30fe1b87a4530564d1d74e41dcbd68f 100644 --- a/python-aiohttp.spec +++ b/python-aiohttp.spec @@ -1,7 +1,7 @@ %global _empty_manifest_terminate_build 0 Name: python-aiohttp Version: 3.9.3 -Release: 5 +Release: 6 Summary: Async http client/server framework (asyncio) License: Apache 2 URL: https://github.com/aio-libs/aiohttp @@ -17,6 +17,8 @@ Patch3: CVE-2024-30251-PR-8335-5a6949da-backport-3.9-Add-Content-Disposi # https://github.com/aio-libs/aiohttp/commit/9ba9a4e531599b9cb2f8cc80effbde40c7eab0bd Patch4: Fix-Python-parser-to-mark-responses-without-length-a.patch Patch5: CVE-2024-42367.patch +#https://github.com/aio-libs/aiohttp/commit/bc15db61615079d1b6327ba42c682f758fa96936 +Patch6: CVE-2024-52303.patch Requires: python3-attrs Requires: python3-charset-normalizer @@ -92,6 +94,9 @@ mv %{buildroot}/doclist.lst . %{_docdir}/* %changelog +* Tue Nov 19 2024 Yu Peng - 3.9.3-6 +- Fix CVE-2024-52303 + * Fri Oct 11 2024 yaoxin - 3.9.3-5 - Fix CVE-2024-42367