GuardAPI Logo
GuardAPI

Fix API Rate Limit Exhaustion in Blitz.js

Blitz.js abstracts the API layer through its RPC architecture, which often leads developers to forget that every mutation and query is a public-facing POST endpoint. Without explicit rate limiting, an attacker can weaponize these endpoints to perform credential stuffing, resource exhaustion, or database DoS. To secure Blitz, we must inject a throttling layer into the resolver pipe to intercept and drop malicious traffic before it hits the business logic.

The Vulnerable Pattern

// src/auth/mutations/resetPassword.ts
import { resolver } from "@blitzjs/rpc"
import db from "db"

export default resolver.pipe( async ({ password, token }) => { // VULNERABILITY: No rate limiting here. // An attacker can spam this endpoint to brute-force tokens // or exhaust database connections. const user = await db.user.update({ where: { resetToken: token }, data: { hashedPassword: password }, }) return user } )

The Secure Implementation

The secure implementation utilizes a 'Sliding Window' algorithm via Redis to track request counts per IP address. By placing the rate-limiting logic at the start of the 'resolver.pipe', we ensure that unauthorized or excessive requests are rejected immediately. This prevents 'expensive' operations—like bcrypt hashing or complex Prisma queries—from executing. For production Blitz.js apps, use a distributed store like Redis rather than in-memory stores to ensure limits persist across serverless function cold starts and multiple pod instances.

// src/lib/ratelimit.ts
import { Ratelimit } from "@upstash/ratelimit"
import { Redis } from "@upstash/redis"

export const limiter = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(5, “1 m”), })

// src/auth/mutations/resetPassword.ts import { resolver } from “@blitzjs/rpc” import { limiter } from “src/lib/ratelimit”

export default resolver.pipe( async (input, ctx) => { const ip = ctx.ip || “anonymous” const { success } = await limiter.limit(reset-password:${ip}) if (!success) throw new Error(“Too many requests. Slow down, hacker.”) return input }, async ({ password, token }) => { const user = await db.user.update({ where: { resetToken: token }, data: { hashedPassword: password }, }) return user } )

System Alert • ID: 3666
Target: Blitz.js API
Potential Vulnerability

Your Blitz.js API might be exposed to API Rate Limit Exhaustion

74% of Blitz.js apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.

RUN FREE SECURITY DIAGNOSTIC
GuardLabs Engine: ONLINE

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.