Cloudanix VulnDB

CVE-2026-48587

Low · 3.1

CVSS

3.1

EPSS

0.4%

Published

Jun 3, 2026

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

A caching mistake in some Django applications could let one person see another person’s cached page content under specific conditions.

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 cache Vary-header handling can compare header names without trimming leading or trailing whitespace. If an application returns a cacheable response with a whitespace-padded Vary value such as `Vary: Cookie` or `Vary: Authorization `, Django may fail to recognize that the response should vary on that request header. In affected caching configurations, a response intended to be separated per user, session, authorization token, language, or similar request attribute may be stored and later served to a different requester. The result is unintended disclosure of cached response content. The issue affects Django 5.2 before 5.2.15 and 6.0 before 6.0.6; unsupported earlier branches were not evaluated and may also be affected.

Why it matters to the business

Organizations using Django caching for pages or API responses could accidentally expose one user's cached content to another user if affected responses contain malformed whitespace-padded Vary headers. The most likely impact is privacy or confidentiality exposure, such as account details, personalized pages, session-dependent content, or other data embedded in cached responses. The CVSS and EPSS values indicate relatively low expected exploitation at scale, and it is not in CISA KEV, but internet-facing Django applications with shared caches should still prioritize remediation because cache leaks can be hard to detect after the fact.

How an attack unfolds

An attacker identifies a Django endpoint whose response is cacheable and includes a Vary header with leading or trailing whitespace around a security-relevant header name, for example Cookie or Authorization. A legitimate user or the attacker first causes a personalized response to be generated and stored in the Django cache. Because the affected Django logic does not normalize the Vary value before comparison, the cache may not key the response on the intended request header. The attacker then requests the same URL with different or absent session-specific headers and receives the cached response that should have been isolated to another request context. Successful exploitation depends on the application emitting whitespace-padded Vary values, using Django's affected cache handling, and caching content that contains information specific to a user or request.

How to fix it

Upgrade Django to a fixed release: Django 5.2.x deployments should upgrade to 5.2.15 or later, and Django 6.0.x deployments should upgrade to 6.0.6 or later. If running an unsupported Django branch such as 5.0.x, 4.1.x, or 3.2.x, migrate to a supported fixed branch because those series were not evaluated and may be affected. As a temporary mitigation, audit and normalize all Vary headers so header names are trimmed and canonicalized before responses are cached; avoid caching personalized, authenticated, or session-dependent responses unless the cache key reliably varies on the correct request headers. Consider disabling page-level caching for sensitive endpoints until the framework is upgraded and cache behavior is validated. Purge application, reverse-proxy, CDN, and shared cache layers after remediation to remove any incorrectly keyed cached responses.

How to confirm the fix worked

Confirm the installed Django version is 5.2.15 or later for the 5.2 series, or 6.0.6 or later for the 6.0 series. Review dependency lockfiles, container images, virtual environments, and deployed artifacts rather than relying only on source manifests. Exercise representative cached endpoints and inspect response headers to ensure Vary values do not contain leading or trailing whitespace. For sensitive endpoints, test with two different authenticated users or request contexts and verify the cache does not return the same personalized response across users. Review cache keys or cache metadata, where available, to confirm the intended request headers are included in cache variation. After patching, purge cache stores and verify fresh responses are generated with normalized Vary handling.

Typical attack path

  1. Find a Django application or endpoint that uses Django response caching or cache middleware.
  2. Identify cacheable URLs that return user-specific or request-specific content.
  3. Confirm the response contains a whitespace-padded Vary header value, such as a leading or trailing space around Cookie, Authorization, or another request header name.
  4. Cause or wait for a victim or authenticated request to populate the cache for that URL.
  5. Request the same URL using different session, authorization, or preference headers.
  6. Observe whether the application serves cached content belonging to a different request context.

How to detect it

Look for evidence that cacheable Django responses with malformed Vary headers were served across different users or request contexts. Useful sources include Django application access logs, application response-header logs, reverse-proxy logs, CDN logs, cache middleware logs, cache backend telemetry, and web application firewall logs. Search for responses containing Vary headers with leading or trailing whitespace around values such as Cookie, Authorization, Accept-Language, Accept-Encoding, or Origin. Correlate cache HIT events for the same URL where different clients, sessions, cookies, authorization headers, or user agents received identical response sizes, ETags, cache keys, or bodies. Investigate reports of users seeing another user's data, unexpected account information, or inconsistent personalized content. Where cache contents are inspectable, sample cached objects for sensitive data and compare their cache metadata against the headers that should have contributed to the cache key. Absence of obvious exploit strings is expected; this issue is typically detected through cache-behavior anomalies and malformed response-header evidence rather than a unique payload.

  • Vary: Cookie
  • Vary: Cookie
  • Vary: Authorization
  • Vary: Authorization
  • Vary: Accept-Language
  • Vary: Accept-Language
  • Vary: Origin
  • Vary: Origin
  • Vary: X-Requested-With
  • Vary: X-Requested-With
  • Cache-Control: public
  • X-Cache: HIT
  • CF-Cache-Status: HIT
  • Age:

What your security team should do

  • Inventory Django applications using Django's cache middleware, per-view caching, or other shared response caching mechanisms.
  • Upgrade affected Django 5.2 deployments to 5.2.15 or later and Django 6.0 deployments to 6.0.6 or later; migrate unsupported Django branches to a supported fixed release.
  • Prioritize internet-facing applications and endpoints that serve authenticated, personalized, or privacy-sensitive content.
  • Audit application code, middleware, upstream proxies, and response-modifying components for Vary headers with leading or trailing whitespace.
  • Temporarily disable caching for sensitive authenticated endpoints if immediate upgrade is not possible.
  • Purge Django cache backends, CDN caches, and reverse-proxy caches after remediation.
  • Add regression tests that assert Vary header values are normalized and that cached personalized responses are not shared across users.
  • Review historical cache and access logs for evidence of cross-user cache hits on sensitive URLs.

The record

An issue was discovered in Django 5.2 before 5.2.15 and 6.0 before 6.0.6. `django.utils.cache.has_vary_header()` in Django does not strip leading or trailing whitespace from `Vary` response header values before comparison, which allows remote attackers to read cached responses via requests to URLs whose responses contain whitespace-padded Vary header 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 Navid Rezazadeh 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