HTTP Cache Poisoning

HTTP Cache Poisoning Illustration

What is HTTP Cache Poisoning?

HTTP cache poisoning is a technique where an attacker manipulates a web cache to serve malicious content to users. By exploiting how caches handle HTTP headers and responses, attackers can inject harmful content that gets cached and served to subsequent visitors.

This attack is particularly dangerous because it can affect multiple users with a single malicious request, and the poisoned content can persist in the cache for extended periods.

Key Concept: Cache poisoning exploits the difference between what the cache considers as the cache key (used to identify cached content) and what actually influences the server's response.

How Cache Poisoning Works

The attack typically follows these steps:

1. Identify Unkeyed Inputs

Find HTTP headers or parameters that influence the server's response but are not included in the cache key. Common unkeyed inputs include:

  • X-Forwarded-Host
  • X-Forwarded-Proto
  • X-Original-URL
  • X-Rewrite-URL
  • User-Agent (sometimes)
  • Accept-Language (sometimes)

2. Craft Malicious Request

Create a request that uses unkeyed inputs to inject malicious content into the response:

GET /vulnerable-page HTTP/1.1
Host: victim.com
X-Forwarded-Host: evil.com

<!-- Server reflects X-Forwarded-Host in response -->
<script src="//evil.com/malicious.js"></script>

3. Cache the Poisoned Response

The cache stores the response using only the keyed inputs (typically the URL and Host header), but the response contains the malicious content influenced by unkeyed inputs.

4. Serve to Victims

Subsequent requests for the same resource receive the poisoned response from the cache, affecting all users until the cache expires.

Types of Cache Poisoning Attacks

Basic Cache Poisoning

Exploiting unkeyed headers that are reflected in the response:

GET /home HTTP/1.1
Host: vulnerable-website.com
X-Forwarded-Host: evil.com

<!-- Response includes -->
<link rel="canonical" href="//evil.com/home">

Cache Poisoning via HTTP Header Injection

Using header injection to manipulate cached responses:

GET /api/data HTTP/1.1
Host: vulnerable-website.com
X-Forwarded-Proto: https\r\nContent-Type: text/html\r\n\r\n<script>alert('XSS')</script>

Cache Poisoning with Parameter Pollution

Exploiting how different systems handle duplicate parameters:

GET /search?q=innocent&q=<script>alert('XSS')</script> HTTP/1.1
Host: vulnerable-website.com

<!-- Cache key: /search?q=innocent -->
<!-- Response includes both parameters -->

Cache Poisoning via Fat GET

Using GET requests with bodies (which some caches ignore but servers process):

GET /vulnerable-endpoint HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30

callback=<script>alert(1)</script>

Web Cache Deception

A related attack where attackers trick caches into storing private content by manipulating URLs:

GET /user/profile/nonexistent.css HTTP/1.1
Host: vulnerable-website.com

<!-- Cache treats this as a static CSS file -->
<!-- Server returns user profile data -->
<!-- Cache stores private data as public -->

Warning: Cache poisoning attacks can persist for hours or days depending on cache TTL settings, potentially affecting thousands of users with a single malicious request.

Detection and Exploitation Techniques

Cache Key Discovery

Identify what constitutes the cache key by testing various headers and parameters:

  • Send requests with different header values and observe cache behavior
  • Use cache-busting parameters to test cache key composition
  • Analyze cache headers like X-Cache, CF-Cache-Status, or Age

Unkeyed Input Identification

Find headers that influence responses but aren't part of the cache key:

# Test common unkeyed headers
X-Forwarded-Host: evil.com
X-Forwarded-Proto: https
X-Original-URL: /admin
X-Rewrite-URL: /admin
X-HTTP-Method-Override: POST

Cache Buster Techniques

Use cache-busting parameters to ensure fresh responses during testing:

GET /target?cachebuster=12345 HTTP/1.1
Host: vulnerable-website.com
X-Forwarded-Host: evil.com

Automated Tools

Tools for cache poisoning detection:

  • Param Miner (Burp Suite extension) - discovers unkeyed inputs
  • Web Cache Vulnerability Scanner - automated cache poisoning detection
  • Custom scripts for cache behavior analysis

Defense Strategies

Secure Cache Configuration

Configure caches to include security-relevant headers in cache keys:

  • Include X-Forwarded-Host in cache key if used by the application
  • Normalize header values before caching
  • Set appropriate cache TTL values
  • Use Vary headers to control cache key composition

Input Validation and Sanitization

Validate and sanitize all inputs that might be reflected in responses:

// Example: Validate X-Forwarded-Host
const allowedHosts = ['example.com', 'www.example.com'];
const forwardedHost = req.headers['x-forwarded-host'];

if (forwardedHost && !allowedHosts.includes(forwardedHost)) {
  // Reject or sanitize the header
  delete req.headers['x-forwarded-host'];
}

Disable Unnecessary Headers

Remove or ignore headers that aren't needed by your application:

  • Strip X-Forwarded-* headers if not behind a trusted proxy
  • Ignore X-Original-URL and X-Rewrite-URL if not used
  • Validate User-Agent if it influences responses

Implement Cache-Control Headers

Use appropriate cache-control directives:

# For sensitive content
Cache-Control: no-cache, no-store, must-revalidate

# For public content with validation
Cache-Control: public, max-age=3600, must-revalidate

# Include Vary header for content that varies by header
Vary: Accept-Encoding, User-Agent

Content Security Policy

Implement CSP to mitigate the impact of successful cache poisoning:

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-random123'; object-src 'none';

Regular Security Testing

Conduct regular testing for cache poisoning vulnerabilities:

  • Test all endpoints that might be cached
  • Verify cache key composition
  • Test with various unkeyed headers
  • Monitor cache behavior in production

Best Practice: Implement a defense-in-depth strategy combining secure cache configuration, input validation, and monitoring. Cache poisoning attacks can be subtle and persistent, requiring comprehensive protection.