Security

Rate Limiting & Abuse Prevention

Intermediate

Any endpoint open to the world will be hit hard — by brute-force login attempts, credential stuffing, scrapers, and accidental client loops. Rate limiting caps how often a caller can hit an endpoint, which turns these from a real threat into a blocked one. It is a cheap control that protects both security and availability.

Without limits, attackers can try millions of passwords, list out accounts, scrape data, or simply overwhelm the service. A buggy client can also take you down by accident. Rate limiting, and related controls (throttling, quotas, lockouts, and CAPTCHAs where they fit), limits the damage any single caller can do.

Apply it especially to sensitive and expensive endpoints: authentication, password reset, KYC, payments, and anything that triggers a costly downstream call. Combine it with the wider fail-safe approach (see Secure Defaults, Designing for Failure).

Limit and throttle

Unlimited login [HttpPost("/login")] public IActionResult Login(Creds c) { ... }
// no limit, no lockout

An attacker can try unlimited passwords against one account (brute force), or the same password across many accounts (credential stuffing), at machine speed. The door is wide open.

Limited, monitored [EnableRateLimiting("auth")] // e.g. 5/min per IP+account, shared store
[HttpPost("/login")] public IActionResult Login(Creds c) { ... }
// repeated failures -> backoff/lock; spikes -> alert

Brute force and stuffing are slowed to a trickle that is no use, repeated failures trigger a lockout, and an attack shows up in monitoring.

Fail and respond well

Self-review checklist

Why it matters: Rate limiting is a small amount of code that defeats some of the most common attacks — brute force, credential stuffing, scraping, and basic denial of service — while also protecting availability from runaway clients. On public financial endpoints it is not optional hardening. It is a baseline control.