Fix API Rate Limit Exhaustion in Fresh
Fresh applications running on Deno are highly performant but vulnerable to resource exhaustion if handlers lack ingress control. Without rate limiting, attackers can weaponize your API endpoints to drain upstream quotas or induce a Denial of Service (DoS). The fix involves implementing a middleware layer that tracks request frequency per client and enforces a hard cap.
The Vulnerable Pattern
// routes/api/data.ts import { Handlers } from "$fresh/server.ts";
export const handler: Handlers = { async GET(_req, _ctx) { // VULNERABILITY: No restriction on how many times this can be called. // An attacker can script 10k requests/sec to exhaust the upstream API key. const res = await fetch(“https://api.external-service.com/v1/resource”); const data = await res.json(); return Response.json(data); }, };
The Secure Implementation
The secure implementation moves the logic to a Fresh middleware, intercepting requests before they reach the handler. It uses a 'Fixed Window' algorithm to track IP addresses in a Map (use Redis for distributed environments). When a client exceeds the threshold (100 requests per minute), the server terminates the request early with a HTTP 429 status code. This prevents the execution of expensive downstream logic and protects the application from automated abuse.
// routes/_middleware.ts import { MiddlewareHandlerContext } from "$fresh/server.ts";const RATELIMIT_WINDOW = 60 * 1000; // 1 minute const MAX_REQUESTS = 100; const hits = new Map<string, { count: number; reset: number }>();
export async function handler(req: Request, ctx: MiddlewareHandlerContext) { if (ctx.destination !== “route”) return await ctx.next();
const ip = ctx.remoteAddr.hostname; const now = Date.now(); const record = hits.get(ip) || { count: 0, reset: now + RATELIMIT_WINDOW };
if (now > record.reset) { record.count = 0; record.reset = now + RATELIMIT_WINDOW; }
if (record.count >= MAX_REQUESTS) { return new Response(“Too Many Requests”, { status: 429, headers: { “Retry-After”: Math.ceil((record.reset - now) / 1000).toString() } }); }
record.count++; hits.set(ip, record); return await ctx.next(); }
Your Fresh API
might be exposed to API Rate Limit Exhaustion
74% of Fresh 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.