Fix API Rate Limit Exhaustion in Next.js
Next.js API routes are sitting ducks for automated resource exhaustion. Without a sliding window or token bucket mechanism, an attacker can flood your serverless functions, spiking costs and inducing a DoS. You're basically handing over a blank check to anyone with a bash script. To secure this, you need a centralized state—like Redis—to track request frequency across distributed instances.
The Vulnerable Pattern
export default async function handler(req, res) {
// VULNERABLE: No check on request frequency.
// An attacker can call this 10,000 times a second to exhaust DB connections or API credits.
const data = await db.performExpensiveQuery();
return res.status(200).json(data);
}
The Secure Implementation
The secure implementation leverages a sliding window algorithm backed by Redis. Unlike local memory variables which reset on every serverless cold start, Redis provides a persistent, shared state for all incoming requests. We identify the client using the 'x-forwarded-for' header (ensure your proxy is trusted to prevent IP spoofing). If the 'success' flag is false, we terminate the execution early with an HTTP 429 status, shielding the expensive database logic from the load.
import { Ratelimit } from "@upstash/ratelimit"; import { Redis } from "@upstash/redis";const redis = new Redis({ url: process.env.UPSTASH_REDIS_REST_URL, token: process.env.UPSTASH_REDIS_REST_TOKEN, });
// Create a new rate limiter: 10 requests per 10 seconds const ratelimit = new Ratelimit({ redis: redis, limiter: Ratelimit.slidingWindow(10, “10 s”), });
export default async function handler(req, res) { const identifier = req.headers[“x-forwarded-for”] || “anonymous”; const { success, limit, reset, remaining } = await ratelimit.limit(identifier);
res.setHeader(“X-RateLimit-Limit”, limit.toString()); res.setHeader(“X-RateLimit-Remaining”, remaining.toString()); res.setHeader(“X-RateLimit-Reset”, reset.toString());
if (!success) { return res.status(429).json({ error: “Too many requests. Slow down, script kiddie.” }); }
const data = await db.performExpensiveQuery(); return res.status(200).json(data); }
Your Next.js API
might be exposed to API Rate Limit Exhaustion
74% of Next.js apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.