Cache Poisoning Attack
How Cache Poisoning Works
Cache poisoning is a web attack technique where an attacker manipulates a cache to serve malicious content to other users. The attack exploits the fundamental trust that caching systems place in their inputs.
The attack typically follows these steps:
- Identify cacheable endpoint: Find an API endpoint that returns cacheable responses (often without proper cache-control headers)
- Craft malicious input: Create a request with parameters that the cache will store separately from other inputs
- Trigger cache storage: Send the request so the cache stores the malicious response
- Wait for victim requests: When legitimate users make similar requests, they receive the poisoned cached response
A classic example: an API endpoint like /api/products?search=shoes might cache responses without proper validation. An attacker could request /api/products?search=shoes%3B%20DROP%20TABLE%20users, causing the cache to store a response that includes error messages or malformed data. Subsequent legitimate requests for shoes would then serve the poisoned response to all users.
Cache Poisoning Against APIs
APIs are particularly vulnerable to cache poisoning because they often handle sensitive data and are frequently cached at multiple layers: CDN, reverse proxy, application server, and client-side. The attack surface is broader than traditional web applications.
Common API cache poisoning scenarios include:
- Parameter manipulation: Exploiting how APIs construct cache keys from query parameters or headers
- Header injection: Manipulating HTTP headers like Accept-Language or User-Agent to create cache splits
- Authentication bypass: Finding endpoints that cache responses for unauthenticated users and serving them to authenticated users
- Content-type confusion: Poisoning caches to serve JSON responses as HTML, enabling XSS attacks
For example, an e-commerce API might cache product recommendations. An attacker could manipulate the request to include malicious product IDs that, when cached, cause the system to recommend harmful or inappropriate products to all users. The cache doesn't distinguish between legitimate and malicious requests, so once poisoned, it serves the same malicious content to everyone.
middleBrick's cache poisoning detection specifically tests for these vulnerabilities by sending requests with manipulated parameters and headers, then verifying if the cache stores and serves the modified responses to subsequent requests.
Detection & Prevention
Detecting cache poisoning requires monitoring for unusual cache behavior and validating cache integrity. Key detection methods include:
- Cache key analysis: Reviewing how cache keys are constructed to ensure they include all relevant security parameters
- Response validation: Implementing strict validation of cached responses before serving them
- Monitoring cache hit ratios: Unusual spikes in cache hits for specific keys can indicate poisoning attempts
- Regular cache purging: Scheduled invalidation of suspicious cache entries
Prevention strategies are more effective than detection:
- Strict cache control headers: Use Cache-Control: private for sensitive responses, implement proper max-age values
- Input validation: Sanitize all parameters before processing or caching
- Cache key normalization: Ensure cache keys are constructed consistently and securely
- Authentication-aware caching: Never cache responses that depend on user authentication state
- Content Security Policy: Implement CSP headers to mitigate XSS attacks from poisoned content
middleBrick scans APIs for cache poisoning vulnerabilities by testing how the system handles manipulated inputs and whether malicious responses get cached and served to other users. The scanner checks for missing cache-control headers, improper cache key construction, and whether the API properly validates inputs before caching.
For APIs handling sensitive data, consider implementing cache-busting techniques like including user-specific tokens in cache keys, or using server-side session storage instead of client-side caching for authentication-dependent responses.