Vulnerability

Web Cache Poisoning
detect, understand, remediate

Web cache poisoning manipulates caching systems by injecting malicious content through unkeyed inputs (headers, cookies), causing the poisoned response to be served to every subsequent visitor.

No credit card required. Free plan available forever.

Severity

High

CWE ID

CWE-349

OWASP Top 10

A05:2021 – Security Misconfiguration

CVSS 3.1 Score

7.2

What is web cache poisoning?

Web cache poisoning (CWE-349) is an attack technique where an adversary manipulates a web cache to serve malicious content to other users. The attack works by finding inputs that are not part of the cache key (called "unkeyed" inputs) but still influence the server's response. When the attacker injects a payload through an unkeyed input, the poisoned response is cached and subsequently served to every user who requests the same resource.

Modern web architectures rely heavily on caching layers, including CDNs, reverse proxies, and application-level caches, to improve performance and reduce server load. This makes cache poisoning a high-impact vulnerability because a single poisoned request can affect thousands or millions of users. The attack is closely related to HTTP request smuggling, as both exploit discrepancies in how intermediaries and backends process requests.

Cache poisoning attacks can deliver a range of payloads, from stored cross-site scripting that executes in every visitor's browser, to redirects that send users to phishing sites, to denial-of-service conditions where error pages are cached for popular resources. The vulnerability is especially dangerous because it persists until the cache entry expires or is purged, and the attacker does not need to maintain an active connection. Host header injection is one of the most common vectors used to achieve cache poisoning in practice.

How it works

1

Identify cached responses

The attacker probes the target to determine which responses are cached by examining cache-related headers (X-Cache, Age, CF-Cache-Status) and observing response time patterns for repeated requests.

2

Find unkeyed input

Using cache buster parameters to isolate tests, the attacker systematically injects values into HTTP headers (X-Forwarded-Host, X-Original-URL), cookies, and other inputs that are not included in the cache key.

3

Inject payload via unkeyed input

Once an unkeyed input that reflects in the response is found, the attacker injects a malicious payload, such as a script tag via X-Forwarded-Host that gets reflected in link or script elements on the page.

4

Poisoned response served to users

The server generates a response containing the attacker's payload, the cache stores it under the legitimate cache key, and every subsequent user who requests that URL receives the poisoned content.

Common causes

Caching unkeyed headers

Cache configurations that exclude HTTP headers from the cache key while the backend application reflects those headers in the response body, creating a mismatch between what is cached and what varies.

Inconsistent cache key configuration

Cache servers and CDNs that use a simplified cache key (e.g., URL path only) while the origin server generates different responses based on additional inputs like query parameters, headers, or cookies.

X-Forwarded-Host reflection

Applications that use the X-Forwarded-Host or X-Forwarded-Scheme headers to generate absolute URLs in the response (meta tags, canonical links, script sources) without including these headers in the cache key.

Fat GET requests with bodies

Some frameworks process request bodies on GET requests, and cache servers ignore the body when computing the cache key. Attackers can inject payloads in the GET body that affect the response but are invisible to the cache.

How to detect it

Automated detection

  • SecPortal's external scanning analyzes cache headers across all discovered endpoints, identifying cached responses and testing for unkeyed input reflection
  • Automated header injection probing tests common unkeyed headers (X-Forwarded-Host, X-Forwarded-Scheme, X-Original-URL) against cached endpoints to detect reflection
  • Cache configuration auditing identifies mismatches between Vary headers and actual response variation, revealing inputs that affect responses but are excluded from the cache key

Manual testing

  • Append a unique cache buster parameter to isolate test requests, then inject values into HTTP headers and observe whether the injected content appears in the cached response
  • Test for X-Forwarded-Host and X-Forwarded-Scheme injection by setting these headers to attacker-controlled domains and checking if generated URLs in the response reflect the injected values
  • Remove the cache buster and send the poisoned request repeatedly until a cache hit is observed, then verify from a different IP or browser that the poisoned content is served from cache

How to fix it

Restrict the cache key to include all varying inputs

Ensure every input that influences the response is included in the cache key. If the backend uses X-Forwarded-Host to generate URLs, the cache must key on that header. Use the Vary header to signal this to downstream caches.

Strip unkeyed inputs at the edge

Configure your CDN or reverse proxy to strip or normalize headers like X-Forwarded-Host, X-Original-URL, and X-Rewrite-URL before they reach the origin server, eliminating them as injection vectors.

Cache only truly static content

Limit caching to responses that are genuinely static and do not vary based on any user input. For dynamic pages, use cache-control: no-store or private directives to prevent shared caching entirely.

Add Vary headers for all dynamic inputs

When responses vary by header, cookie, or other input, include the appropriate Vary header so caches know to maintain separate entries for each variation, preventing cross-user contamination.

Implement CDN-level cache poisoning protections

Use CDN features like request header allow-listing, origin shield, and cache tag-based purging. Configure WAF rules to detect and block requests with suspicious header values targeting cache poisoning.

Compliance impact

Detect cache poisoning vectors

SecPortal identifies unkeyed inputs, cache header misconfigurations, and reflection patterns that enable cache poisoning. Start free.

No credit card required. Free plan available forever.