Refactor rate limiting with exponential backoff strategy
- Update rate limiter to use exponential backoff instead of fixed limit - Implement progressive delays for failed login attempts (0.5s, 1s, 2s, 4s, 5s max) - Update auth router documentation and endpoint docs - Refactor test suite to match new rate limiting behavior - Update backend development documentation - Clean up unused tasks documentation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -2169,17 +2169,22 @@ await config_service.update_global_config(socket_path, update) # Validates agai
|
||||
|
||||
### Login Rate Limiting
|
||||
|
||||
The login endpoint (`POST /api/auth/login`) is protected against brute-force attacks using an in-memory rate limiter.
|
||||
The login endpoint (`POST /api/auth/login`) is protected against brute-force attacks using an in-memory exponential backoff rate limiter.
|
||||
|
||||
**Design:**
|
||||
- Uses a `dict[str, deque[float]]` keyed by client IP, storing login attempt timestamps within a time window.
|
||||
- Attempts outside the window are automatically removed during validation checks.
|
||||
- Uses a `dict[str, deque[float]]` keyed by client IP, storing failed login timestamps within a time window.
|
||||
- Old failures outside the time window are automatically pruned during validation checks.
|
||||
- Expired IP entries are cleaned up to prevent unbounded memory growth.
|
||||
|
||||
**Rate Limit Rules:**
|
||||
- **5 attempts per 60 seconds** per IP address.
|
||||
- Requests exceeding the limit return **HTTP 429 Too Many Requests** with a `Retry-After` header.
|
||||
- Each failed login triggers a progressive server-side delay (exponential back-off, 1–10 seconds) to further slow attacks, on top of bcrypt hashing (~100ms). The penalty grows with consecutive failures and resets after the rate-limit window expires. Concurrency protection caps the delay when multiple penalty tasks are already running for the same IP.
|
||||
- **Exponential backoff:** Each failed login attempt incurs a progressively longer delay before the next attempt is allowed:
|
||||
- 1st failure: 1 × 2¹ = 2 seconds
|
||||
- 2nd failure: 1 × 2² = 4 seconds
|
||||
- 3rd failure: 1 × 2³ = 8 seconds
|
||||
- 4th+ failures: capped at 10 seconds (max)
|
||||
- Failed attempts that arrive during the backoff period return **HTTP 429 Too Many Requests** with a `Retry-After` header indicating the remaining wait time.
|
||||
- Each failed login is also accompanied by bcrypt password hashing (~100ms), providing additional computational resistance.
|
||||
- The backoff counter resets after the rate-limit window (60 seconds by default) expires with no new failures.
|
||||
|
||||
**IP Extraction (Proxy Safety):**
|
||||
- When behind nginx, the rate limiter reads the real client IP from `X-Forwarded-For` or `X-Real-IP` headers.
|
||||
|
||||
Reference in New Issue
Block a user