CVE-2026-8404
Low · 3.1CVSS
3.1
EPSS
0.4%
Published
Jun 3, 2026
CISA due date
—
Cloudanix analysis
Some Django websites may accidentally save and show private pages to the wrong visitor if caching instructions were written with unusual capitalization.
- Exploitation
- Requires User Interaction
- Attacker needs
- User Interaction
- Complexity
- Moderate
- Impact
- Data Exposure
- Component
- Web Framework
- Class
- Information Disclosure
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
Django’s UpdateCacheMiddleware fails to evaluate Cache-Control response directives in a case-insensitive way. HTTP directive names are intended to be case-insensitive, but affected Django versions may not recognize uppercase or mixed-case directives such as NO-STORE, Private, or No-Cache. If an application emits those directives with non-lowercase casing, Django may incorrectly store a response that was meant to be non-cacheable. A later unauthenticated or differently authenticated requester could then receive that cached response, causing unintended disclosure of response content. The impact depends on whether the application uses Django’s cache middleware, whether sensitive responses rely on Cache-Control to prevent caching, and whether those directives are emitted with uppercase or mixed-case values.
Why it matters to the business
The main risk is accidental exposure of private or user-specific web content through shared caching. This could include account pages, personalized responses, limited-access content, or other data that the application expected Django not to cache. The CVSS and EPSS values indicate low expected exploitation activity, it is not listed in CISA KEV, and no exploit maturity is currently reported; however, because Django is widely used and unsupported older branches may also be affected, organizations should still prioritize review and patching for internet-facing applications that use Django cache middleware.
How an attack unfolds
An attacker identifies a Django application using UpdateCacheMiddleware and pages whose responses include Cache-Control directives intended to prevent caching, but where those directives are uppercase or mixed-case. In a typical scenario, a legitimate user or attacker-controlled session first causes the application to generate a sensitive or personalized response. Because the vulnerable middleware does not recognize the non-lowercase Cache-Control directive correctly, it may store that response in the configured cache. The attacker then requests the same cache key, URL, and relevant request variation conditions, and Django serves the previously cached response. Successful exploitation depends on application-specific cache key behavior, response variation headers, authentication handling, and whether sensitive pages are routed through the cache middleware.
How to fix it
Upgrade Django to a fixed release: use Django 5.2.15 or later for the 5.2 series, or Django 6.0.6 or later for the 6.0 series. If using an unsupported Django branch such as 5.0.x, 4.1.x, or 3.2.x, upgrade to a supported fixed branch because those series were not evaluated and may also be affected. As a defense-in-depth mitigation, ensure applications emit Cache-Control directives in lowercase where possible, especially no-store, no-cache, private, and max-age=0. Review use of UpdateCacheMiddleware and FetchFromCacheMiddleware around authenticated or personalized views; avoid routing sensitive authenticated content through shared caching unless vary and cache-key behavior is explicitly safe. Consider temporarily disabling Django site-wide cache middleware for sensitive applications until patched. Purge shared caches after patching if sensitive responses may have been stored.
How to confirm the fix worked
Confirm the installed Django version is 5.2.15 or later, 6.0.6 or later, or another vendor-confirmed fixed release. Verify dependency lockfiles, containers, virtual environments, and deployed runtime packages rather than only source manifests. Review middleware settings for django.middleware.cache.UpdateCacheMiddleware and django.middleware.cache.FetchFromCacheMiddleware. Test representative sensitive endpoints by returning Cache-Control directives in uppercase or mixed-case and confirming they are not cached or served to a separate session. Inspect configured cache backends and reverse proxies for entries corresponding to sensitive URLs, then purge any suspect cached objects. Validate that authenticated and personalized responses include appropriate Vary behavior and are not stored in shared caches.
Typical attack path
- Reconnoiter the target application for Django behavior, cacheable endpoints, and responses containing uppercase or mixed-case Cache-Control directives.
- Identify pages that return user-specific, private, or authorization-dependent content while relying on Cache-Control to prevent caching.
- Cause a sensitive response to be generated, either through attacker-controlled activity or by waiting for another user to access the affected page.
- Trigger Django’s cache middleware to incorrectly store the response because it does not recognize the directive casing.
- Request the same URL or cache key conditions and receive a cached response that should not have been shared.
- Extract any exposed private, personalized, or restricted content from the cached response.
How to detect it
Look for evidence that sensitive responses were cached and later served to other users or unauthenticated clients. Relevant sources include Django application logs, web server access logs, cache backend logs, reverse proxy logs, CDN logs, and application audit logs for authenticated page access. Focus on endpoints that return personalized or restricted content and include Cache-Control directives with uppercase or mixed-case values. Compare response headers and cache-status headers across users; suspicious patterns include cache HIT responses for authenticated pages, identical response sizes or entity tags served to different users, private pages served without a corresponding application-side authorization event, and repeated requests to the same URL from different sessions shortly after a privileged user accessed it. If cache backend logging is available, search for stored keys corresponding to authenticated or sensitive routes. No public threat actor activity or KEV exploitation is currently reported for this issue, so detection should emphasize exposure validation and cache misuse artifacts rather than known malware indicators.
- django.middleware.cache.UpdateCacheMiddleware
- django.middleware.cache.FetchFromCacheMiddleware
- Cache-Control: NO-STORE
- Cache-Control: NO-CACHE
- Cache-Control: PRIVATE
- Cache-Control: No-Store
- Cache-Control: No-Cache
- Cache-Control: Private
- Cache-Control: Max-Age=0
- Cache-Control: MUST-REVALIDATE
- Cache-Control: Proxy-Revalidate
- X-Cache: HIT
- CF-Cache-Status: HIT
- Age:
What your security team should do
- Inventory Django applications and prioritize internet-facing systems using Django cache middleware.
- Upgrade affected Django deployments to 5.2.15 or later, 6.0.6 or later, or a supported fixed branch.
- Move unsupported Django versions to a supported release line; do not assume unsupported series are safe.
- Search application code, middleware, decorators, and response-building logic for uppercase or mixed-case Cache-Control directives.
- Temporarily disable site-wide Django cache middleware for authenticated or sensitive areas if immediate patching is not possible.
- Purge application cache backends and intermediary caches after remediation where sensitive responses may have been cached.
- Add regression tests verifying that no-store, no-cache, and private directives prevent caching regardless of directive casing.
- Review access logs for repeated unauthenticated or cross-session requests to personalized URLs that were unexpectedly served from cache.
The record
An issue was discovered in Django 5.2 before 5.2.15 and 6.0 before 6.0.6. `django.middleware.cache.UpdateCacheMiddleware` in Django does not match `Cache-Control` response directives case-insensitively, which allows remote attackers to read responses that were incorrectly cached because their `Cache-Control` directives used uppercase or mixed-case values. Earlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected. Django would like to thank Ahmed Badawe for reporting this issue.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| openSUSE:Leap 16.0 | python-Django | 0 | 5.2.4-bp160.9.1 |
| openSUSE:Tumbleweed | python-Django | 0 | 5.2.15-1.1 |
| openSUSE:Tumbleweed | python-Django4 | 0 | 4.2.30-3.1 |
| openSUSE:Tumbleweed | python-Django6 | 0 | 6.0.6-1.1 |
Related vulnerabilities
- CVE-2026-7666 An issue was discovered in Django 6.0 before 6.0.6 and 5.2 before 5.2.15. Also affects python-Django
- CVE-2026-6873 An issue was discovered in Django 6.0 before 6.0.6 and 5.2 before 5.2.15. Also affects python-Django
- CVE-2026-48587 An issue was discovered in Django 5.2 before 5.2.15 and 6.0 before 6.0.6. Also affects python-Django
- CVE-2026-35193 An issue was discovered in Django 5.2 before 5.2.15 and 6.0 before 6.0.6. Also affects python-Django
- CVE-2026-3902 An issue was discovered in 6.0 before 6.0.4, 5.2 before 5.2.13, and 4.2 before 4.2.30. Also affects python-Django
- CVE-2026-4277 An issue was discovered in 6.0 before 6.0.4, 5.2 before 5.2.13, and 4.2 before 4.2.30. Also affects python-Django
- CVE-2026-4292 An issue was discovered in 6.0 before 6.0.4, 5.2 before 5.2.13, and 4.2 before 4.2.30. Also affects python-Django
- CVE-2026-33033 An issue was discovered in 6.0 before 6.0.4, 5.2 before 5.2.13, and 4.2 before 4.2.30. Also affects python-Django