Missing rate limiting
API endpoints with no rate limiting. Lets attackers brute-force passwords, exhaust your API quota, or run up your bill.
What this rule detects
VC008 looks for high-risk endpoints (login, password reset, signup, paid API calls) without a rate-limit middleware in the chain. The rule recognizes common rate-limit libraries (express-rate-limit, upstash/ratelimit, hono/ratelimit) and only fires when none are detected on the path.
Vulnerable vs. safe code
// No rate limit. Attacker can submit 1M password guesses.
export async function POST(req: Request) {
const { email, password } = await req.json();
const user = await db.user.findUnique({ where: { email } });
if (!user || !await bcrypt.compare(password, user.hash)) {
return Response.json({ error: "Invalid" }, { status: 401 });
}
return Response.json({ token: signToken(user.id) });
}import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis";
const ratelimit = new Ratelimit({
redis: Redis.fromEnv(),
// 5 login attempts per IP per 15 minutes.
limiter: Ratelimit.fixedWindow(5, "15 m"),
});
export async function POST(req: Request) {
const ip = req.headers.get("x-forwarded-for") ?? "unknown";
const { success } = await ratelimit.limit(ip);
if (!success) {
return Response.json({ error: "Too many attempts" }, { status: 429 });
}
// ... rest of login logic
}About A04:2021 — Insecure Design
Insecure design captures architectural problems that can't be fixed with a one-line patch — missing rate limits, missing CSRF tokens, business logic that allows abuse. This category is new in the 2021 list and is increasingly common in AI-generated apps because models default to the happy path.
Impact: Missing rate limits on a login endpoint means credential stuffing works. Missing rate limits on a password reset means SMS bombing. Missing rate limits on a paid API endpoint means a $5,000 bill from one bad actor. Most of these don't look like 'security bugs' until you're in incident response.
How to fix it: Build rate limiting in from day one (per IP, per user, per endpoint). Add CSRF tokens to state-changing routes. Think about the threat model: who can call this, how often, and what happens if they call it 1000x more than expected?
Common patterns in this category:
- No rate limiting on authentication endpoints
- Password reset emails sent without throttling
- API endpoints with no per-user request budget
- State-changing routes without CSRF protection
- Business logic that can be replayed indefinitely (e.g. coupon application, vote casting)
Compliance coverage
Findings from this rule map to the following framework controls:
See the full compliance coverage page for how XploitScan maps every rule to SOC 2, ISO 27001, and OWASP Top 10 controls.
Scan your code for VC008 and 157 other rules
Free, no signup. Drag and drop a zip or run npx xploitscan scan .