# Apply rate limiting to authentication endpoints * Status: accepted * Date: 2026-04-26 ## Context and Problem Statement Authentication endpoints (`POST /login`, `POST /` registration) were exposed without any request throttling. An attacker could perform unlimited credential stuffing, dictionary attacks, or account enumeration against these endpoints with no server-side resistance. ## Decision Drivers * Login and registration are the highest-value targets for automated attacks. * No existing infrastructure (WAF, reverse-proxy rate limiting) in front of the API provides this protection at the application layer. * The rate limit must be permissive enough not to affect legitimate users while blocking automated attack patterns. ## Considered Options * No rate limiting (previous state) * Global rate limiting on all routes * Targeted rate limiting on authentication endpoints only ## Decision Outcome Chosen option: "Targeted rate limiting on authentication endpoints", because it provides strong protection where it matters most without risking false positives on data-intensive routes (e.g. Hero Wars analytics endpoints that may legitimately send many requests in a short window). Implementation: `express-rate-limit` middleware with a 10-request / 15-minute window per IP, applied to `POST /api/cms/user/login` and `POST /api/cms/user/` (registration). Returns HTTP 429 with a structured error body on limit exceeded. ### Positive Consequences * Brute force and credential stuffing attacks are throttled to 10 attempts per 15 minutes per IP. * Legitimate users (at most a few login attempts per session) are unaffected. ### Negative Consequences * IP-based rate limiting can be bypassed by attackers rotating IPs or using proxies. * Shared NAT environments (office networks, VPNs) could hit the limit if multiple users attempt to log in simultaneously from the same IP. The 10-request window is generous enough to make this unlikely in practice. * If the API is ever placed behind a reverse proxy, `trust proxy` must be configured in Express so that the correct client IP is used rather than the proxy IP. ## Pros and Cons of the Options ### No rate limiting * Good, because no false positives. * Bad, because unlimited brute force attacks possible. ### Global rate limiting * Good, because protects all endpoints uniformly. * Bad, because risks throttling legitimate use of analytics or data sync endpoints. ### Targeted rate limiting on auth endpoints * Good, because protects the highest-risk endpoints without affecting others. * Good, because easy to tune per endpoint independently. * Bad, because other endpoints (e.g. password reset, if added later) must be manually included. ## Links * Related to [ADR 0006](0006-jwt-authentication.md) — rate limiting protects the JWT issuance endpoint. * Related to [ADR 0008](0008-hmac-sha256-api-key-hashing.md) — API key auth endpoint is protected by the deterministic hash lookup rather than rate limiting.