diff options
| author | Jake Howard <git@theorangeone.net> | 2026-01-14 15:25:45 +0000 |
|---|---|---|
| committer | Jacob Walls <jacobtylerwalls@gmail.com> | 2026-02-03 08:24:42 -0500 |
| commit | f578acc8c54530fffabd52d2db654c8669b011af (patch) | |
| tree | cefccf69ba78097e45739c0a4fd61d8d05207451 /tests | |
| parent | 6dc23508f3395e1254c315084c7334ef81c4c09a (diff) | |
[4.2.x] Fixed CVE-2025-14550 -- Optimized repeated header parsing in ASGI requests.
Thanks Jiyong Yang for the report, and Natalia Bidart, Jacob Walls, and
Shai Berger for reviews.
Backport of eb22e1d6d643360e952609ef562c139a100ea4eb from main.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/asgi/tests.py | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/tests/asgi/tests.py b/tests/asgi/tests.py index f2e293d8bc..9395c8626c 100644 --- a/tests/asgi/tests.py +++ b/tests/asgi/tests.py @@ -7,6 +7,7 @@ from asgiref.testing import ApplicationCommunicator from django.contrib.staticfiles.handlers import ASGIStaticFilesHandler from django.core.asgi import get_asgi_application +from django.core.handlers.asgi import ASGIRequest from django.core.signals import request_finished, request_started from django.db import close_old_connections from django.test import ( @@ -193,6 +194,32 @@ class ASGITest(SimpleTestCase): self.assertEqual(response_body["type"], "http.response.body") self.assertEqual(response_body["body"], b"Echo!") + async def test_meta_not_modified_with_repeat_headers(self): + scope = self.async_request_factory._base_scope(path="/", http_version="2.0") + scope["headers"] = [(b"foo", b"bar")] * 200_000 + + setitem_count = 0 + + class InstrumentedDict(dict): + def __setitem__(self, *args, **kwargs): + nonlocal setitem_count + setitem_count += 1 + super().__setitem__(*args, **kwargs) + + class InstrumentedASGIRequest(ASGIRequest): + @property + def META(self): + return self._meta + + @META.setter + def META(self, value): + self._meta = InstrumentedDict(**value) + + request = InstrumentedASGIRequest(scope, None) + + self.assertEqual(len(request.headers["foo"].split(",")), 200_000) + self.assertLessEqual(setitem_count, 100) + async def test_untouched_request_body_gets_closed(self): application = get_asgi_application() scope = self.async_request_factory._base_scope(method="POST", path="/post/") |
