From 2cb666a3b932cb88b3fd5348448b146523c5940a Mon Sep 17 00:00:00 2001 From: DESIREDDY MOHITH REDDY Date: Sun, 5 Jul 2026 09:22:41 +0530 Subject: [PATCH] fix(security): resolve DoS vulnerability and rate limit bypass in badge rate limiter (#3120) --- src/lib/badge-rate-limit.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/lib/badge-rate-limit.ts b/src/lib/badge-rate-limit.ts index 99b449f48..d3bfa8706 100644 --- a/src/lib/badge-rate-limit.ts +++ b/src/lib/badge-rate-limit.ts @@ -18,8 +18,12 @@ export type BadgeRateLimitResult = { reset: number; }; +let lastPrune = Date.now(); + function pruneStore(now: number): void { if (store.size < 500) return; + if (now - lastPrune < 60000) return; // Only prune once per minute + lastPrune = now; const cutoff = now - WINDOW_MS; for (const [key, entry] of store) { if (entry.windowStart < cutoff) store.delete(key); @@ -61,10 +65,12 @@ export function checkBadgeRateLimit(ip: string): BadgeRateLimitResult { } export function getBadgeClientIp(req: NextRequest): string { + // Use Vercel's trusted IP header or fallback to connection IP + // Do NOT blindly trust x-forwarded-for as it can be easily spoofed return ( - req.headers.get("x-forwarded-for")?.split(",")[0]?.trim() ?? - req.headers.get("x-real-ip") ?? - (req as NextRequest & { ip?: string }).ip ?? + req.headers.get("x-vercel-forwarded-for") || + req.headers.get("x-real-ip") || + (req as NextRequest & { ip?: string }).ip || "unknown" ); }