티스토리 수익 글 보기

티스토리 수익 글 보기

[6.0.x] Fixed CVE-2026-6907 — Prevented caching of requests when Var… · django/django@44ad76e · GitHub
Skip to content

Commit 44ad76e

Browse files
committed
[6.0.x] Fixed CVE-2026-6907 — Prevented caching of requests when Vary header contains an asterisk.
Thank you Ahmad Sadeddin for the report and Jacob Walls for the review. Backport of c79bdfc from main.
1 parent 1b0184a commit 44ad76e

4 files changed

Lines changed: 49 additions & 0 deletions

File tree

django/middleware/cache.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ def process_response(self, request, response):
113113
):
114114
return response
115115

116+
# Don't cache responses when the Vary header contains '*'.
117+
if has_vary_header(response, "*"):
118+
return response
119+
116120
# Page timeout takes precedence over the "max-age" and the default
117121
# cache timeout.
118122
timeout = self.page_timeout

docs/releases/5.2.14.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,13 @@ a cached public page.
3131

3232
This issue has severity "low" according to the :ref:`Django security policy
3333
<security-disclosure>`.
34+
35+
CVE-2026-6907: Potential exposure of private data due to incorrect handling of ``Vary: *`` in ``UpdateCacheMiddleware``
36+
=======================================================================================================================
37+
38+
Previously, :class:`~django.middleware.cache.UpdateCacheMiddleware` would
39+
erroneously cache requests where the ``Vary`` header contained an asterisk
40+
(``'*'``). This could lead to private data being stored and served.
41+
42+
This issue has severity "low" according to the :ref:`Django security policy
43+
<security-disclosure>`.

docs/releases/6.0.5.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ a cached public page.
3232
This issue has severity "low" according to the :ref:`Django security policy
3333
<security-disclosure>`.
3434

35+
CVE-2026-6907: Potential exposure of private data due to incorrect handling of ``Vary: *`` in ``UpdateCacheMiddleware``
36+
=======================================================================================================================
37+
38+
Previously, :class:`~django.middleware.cache.UpdateCacheMiddleware` would
39+
erroneously cache requests where the ``Vary`` header contained an asterisk
40+
(``'*'``). This could lead to private data being stored and served.
41+
42+
This issue has severity "low" according to the :ref:`Django security policy
43+
<security-disclosure>`.
44+
3545
Bugfixes
3646
========
3747

tests/cache/tests.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2513,6 +2513,18 @@ def hello_world_view(request, value):
25132513
return HttpResponse("Hello World %s" % value)
25142514

25152515

2516+
def hello_world_view_patch_vary_headers_asterisk(request, value):
2517+
response = HttpResponse("Hello World %s" % value)
2518+
patch_vary_headers(response, ("*",))
2519+
return response
2520+
2521+
2522+
def hello_world_view_vary_headers_includes_asterisk(request, value):
2523+
response = HttpResponse("Hello World %s" % value)
2524+
response["Vary"] = "Cookie, *, Pony"
2525+
return response
2526+
2527+
25162528
def csrf_view(request):
25172529
return HttpResponse(csrf(request)["csrf_token"])
25182530

@@ -2747,6 +2759,19 @@ def test_cache_control_not_cached(self):
27472759
response = view_with_cache(request, "2")
27482760
self.assertEqual(response.content, b"Hello World 2")
27492761

2762+
def test_vary_asterisk_not_cached(self):
2763+
views_with_cache = (
2764+
cache_page(3)(hello_world_view_patch_vary_headers_asterisk),
2765+
cache_page(3)(hello_world_view_vary_headers_includes_asterisk),
2766+
)
2767+
for view in views_with_cache:
2768+
with self.subTest(view=view):
2769+
request = self.factory.get("/view/")
2770+
response = view(request, "1")
2771+
self.assertEqual(response.content, b"Hello World 1")
2772+
response = view(request, "2")
2773+
self.assertEqual(response.content, b"Hello World 2")
2774+
27502775
def test_sensitive_cookie_not_cached(self):
27512776
"""
27522777
Django must prevent caching of responses that set a user-specific (and

0 commit comments

Comments
 (0)