--- issue: "022" title: "Login rate limiter counts all attempts (not just failures) — users can be locked out after correct logins" severity: major domain: auth labels: [backend, bug] status: open created: 2026-05-29 source: Doc vs Code Audit 2026-05-29 --- # 🟠 Login rate limiter counts all attempts (not just failures) — users can be locked out after correct logins **Severity:** major **Domain:** auth **Labels:** backend, bug ## Description `rateLimitService.checkLoginAttempts()` calls `checkLimit()` which calls `redisService.incr` — incrementing the counter on **every invocation**, before password comparison. The counter is only reset after a full successful login (password verified + session created). With the limit at 5 attempts/15 min, a user who makes 4 correct logins in quick succession (e.g., testing on multiple devices) followed by 1 wrong password will be locked out immediately, even though they never "failed" 5 times in the intended sense. ## Current Behavior 5 total login attempts within 15 minutes (any combination of correct/incorrect passwords) triggers `429 TOO_MANY_ATTEMPTS`. ## Expected Behavior The counter should only increment on **failed** password comparison, not on every attempt. Alternatively, the behaviour should be clearly documented so UX can warn users appropriately. ## Affected Files - `backend/src/services/auth/rateLimitService.ts` — `checkLoginAttempts` / `checkLimit` — counter increment should move to after password comparison in `authController.ts` ## References - [Doc vs Code Audit Report](../09%20-%20Audits/Doc%20vs%20Code%20Audit%20Report%20-%202026-05-29.md) — Finding M3