Cache Poisoning on Aws
How Cache Poisoning Manifests in Aws
Cache poisoning in Aws applications typically exploits the framework's caching mechanisms to inject malicious data that gets served to other users. Aws's built-in cache store and middleware can become attack vectors when user input isn't properly validated before being cached.
The most common Aws cache poisoning scenario involves HTTP response splitting through manipulated headers. Consider this vulnerable Aws code:
const Aws = require('aws-sdk');
const express = require('express');
const app = express();
const cache = require('memory-cache');
app.get('/api/data', (req, res) => {
const userId = req.query.user || 'default';
const cacheKey = `data-${userId}`;
let cachedData = cache.get(cacheKey);
if (!cachedData) {
cachedData = fetchUserData(userId); // Assume this fetches from DB
cache.put(cacheKey, cachedData, 300000); // Cache for 5 minutes
}
res.json(cachedData);
});The vulnerability here is that userId from query parameters is used directly as a cache key without validation. An attacker can craft requests like:
/api/data?user=123%0ACache-Control:%20public,%20max-age=31536000This injects cache-control headers that make sensitive data publicly cacheable. Another attack vector is cache key confusion:
app.get('/api/user/:id', (req, res) => {
const userId = req.params.id;
const cacheKey = `user-${userId}`;
// Vulnerable: No validation that userId is numeric
const userData = cache.get(cacheKey) || fetchUserFromDB(userId);
res.json(userData);
});An attacker could request /api/user/1%0A/2 to create cache keys that overlap with other endpoints or inject path traversal.
Aws's template engine can also be exploited for cache poisoning. When user input is rendered without proper escaping:
app.get('/profile', (req, res) => {
const username = req.query.name || 'guest';
res.render('profile', { username });
});If the template caches the rendered output and username contains HTML or script tags, those get cached and served to other users.
Aws-Specific Detection
Detecting cache poisoning in Aws requires examining both the application code and runtime behavior. middleBrick's Aws-specific scanning identifies these vulnerabilities through several techniques.
Code analysis focuses on finding unsafe cache key construction. middleBrick parses your Aws application to detect patterns like:
middlebrick scan https://your-aws-app.com --framework awsThe scanner looks for:
- Direct use of request parameters (req.query, req.params, req.body) in cache keys
- Missing input validation before caching operations
- Unsafe header manipulation that could affect cache behavior
- Template rendering with unvalidated user input
Runtime detection involves sending crafted requests to trigger cache poisoning conditions. middleBrick tests for:
# Test for header injection vulnerabilities
curl -H "X-Custom: value%0ACache-Control: public" https://your-aws-app.com/api/dataKey indicators of cache poisoning vulnerabilities include:
| Detection Method | What It Identifies | Risk Level |
|---|---|---|
| Cache Key Analysis | Unsafe parameter usage in cache keys | High |
| Header Injection Testing | Response splitting via cache headers | Critical |
| Template Caching Audit | Untrusted data in cached templates | High |
| Cross-User Data Exposure | Cache key collisions between users | High |
middleBrick's Aws-specific checks also verify proper use of cache stores. The scanner flags when:
- Memory-cache or other caching libraries are used without cache key validation
- Redis or other distributed caches accept unvalidated keys
- HttpOnly or secure flags are missing on cached session data
Aws-Specific Remediation
Securing Aws applications against cache poisoning requires a defense-in-depth approach. Here's how to implement proper protections using Aws's native features.
First, validate all inputs before using them in cache operations:
const { validateUserId } = require('./validators');
app.get('/api/data', (req, res) => {
const userId = req.query.user;
if (!validateUserId(userId)) {
return res.status(400).json({ error: 'Invalid user ID' });
}
const cacheKey = `data-${userId}`;
let cachedData = cache.get(cacheKey);
if (!cachedData) {
cachedData = fetchUserData(userId);
cache.put(cacheKey, cachedData, 300000);
}
res.json(cachedData);
});For header validation, use Aws's built-in sanitization:
const sanitize = require('sanitize-headers');
app.use((req, res, next) => {
sanitize(res); // Removes dangerous headers
});Implement strict cache key policies:
function createCacheKey(base, params) {
const sanitizedParams = Object.keys(params).reduce((acc, key) => {
const value = params[key];
if (typeof value === 'string') {
acc[key] = value.replace(/[^a-zA-Z0-9-_]/g, '_'); // Only allow safe characters
}
return acc;
}, {});
return `${base}:${JSON.stringify(sanitizedParams)}`;
}For template rendering, use Aws's built-in escaping:
// In your template engine configuration
app.engine('hbs', exphbs({
defaultLayout: 'main',
helpers: {
safe: function(str) {
return new exphbs.handlebars.SafeString(str);
}
Implement cache poisoning detection middleware:
app.use((req, res, next) => {
const suspiciousHeaders = ['Cache-Control', 'Pragma', 'Expires'];
for (const header of suspiciousHeaders) {
if (req.headers[header.toLowerCase()]) {
console.warn(`Suspicious header detected: ${header}`);
return res.status(400).json({ error: 'Invalid request' });
}
}
next();
});middleBrick's Pro plan includes continuous monitoring that automatically scans your Aws APIs on a configurable schedule, alerting you when new cache poisoning vulnerabilities are detected.