fix(rate-limit): mitigate cache flooding vulnerability (#94)
Update in-memory rate limiter to fail secure (reject new requests) when maximum capacity is reached, rather than evicting the oldest tracking entry. This prevents an attacker from bypassing their rate limit by flooding the store with spoofed `x-forwarded-for` IPs to intentionally trigger cache eviction. Also cleaned up temporary files and updated tests to verify the behavior. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
This commit is contained in:
@@ -103,18 +103,18 @@ describe('checkRateLimit', () => {
|
||||
expect(result.resetAt).toBeLessThanOrEqual(before + 61_000);
|
||||
});
|
||||
|
||||
it('does not crash when store is at capacity and still accepts new IPs', () => {
|
||||
it('does not crash when store is at capacity and prevents rate limit bypasses', () => {
|
||||
// Fill the store beyond MAX_STORE_ENTRIES (10_000 in prod)
|
||||
// by hammering with unique IPs; evictIfFull must silently evict stale entries.
|
||||
// by hammering with unique IPs.
|
||||
const uniqueIps = Array.from({ length: 10005 }, (_, i) => `evict-test-ip-${i}-${Date.now()}`);
|
||||
for (const ip of uniqueIps) {
|
||||
checkRateLimit(ip, 5);
|
||||
}
|
||||
|
||||
// A brand-new IP must still be accepted after potential eviction
|
||||
// A brand-new IP must be blocked to prevent spoofing-based cache floods
|
||||
const freshIp = `evict-fresh-${Date.now()}`;
|
||||
const result = checkRateLimit(freshIp, 5);
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.remaining).toBe(4);
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.remaining).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user