Implement login endpoint rate limiting (TASK-007)

- Add in-memory rate limiter with per-IP deque tracking of attempt timestamps
- Limit login attempts to 5 per 60 seconds per IP, return 429 on excess
- Add Retry-After header to rate limit responses
- Implement IP extraction utility with proxy trust validation (prevent X-Forwarded-For spoofing)
- Integrate rate limiter into auth router and dependencies
- Add 10-second asyncio.sleep on failed login attempts to further slow brute-force
- Add comprehensive tests for rate limiting (9 new tests, all passing)
- Update Features.md to document login rate limiting
- Update Backend-Development.md with rate limiting conventions and design patterns
- Fix test infrastructure issues: update password to meet complexity requirements
- Fix TestValidateSession tests to use Bearer token authentication
- All tests passing: 23 auth tests + full test suite coverage

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-04-26 12:40:52 +02:00
parent 9725714aa2
commit ea4c7c2f85
9 changed files with 414 additions and 73 deletions

View File

@@ -1,62 +1,3 @@
## TASK-005 — `session_cookie_secure` defaults to `false`
**Severity:** Medium
### Where found
`backend/app/config.py``session_cookie_secure: bool = Field(default=False, ...)`.
### Why this is needed
The `Secure` cookie attribute prevents the browser from sending the session cookie over unencrypted HTTP. Defaulting to `false` means that if the production deployment is ever accessed via HTTP (misconfigured nginx, direct backend access, a failed HTTPS redirect), the session token is transmitted in the clear.
### Goal
Default to `true` so production deployments are secure by default. Opt-out explicitly for local development.
### What to do
1. Change `default=False` to `default=True` in the `session_cookie_secure` field.
2. In `Docker/compose.debug.yml`, add `BANGUI_SESSION_COOKIE_SECURE: "false"` explicitly.
3. Document in `compose.debug.yml` comments that `Secure=false` is intentional for local HTTP dev.
### Possible traps and issues
- Browsers reject `Secure` cookies delivered over HTTP — this will break local development unless `compose.debug.yml` is updated.
- Ensure the nginx config in production terminates TLS and passes `X-Forwarded-Proto: https` so FastAPI knows the connection is secure.
### Docs changes needed
- `Backend-Development.md` — document the `session_cookie_secure` config option.
### Doc references
- [Backend-Development.md](Backend-Development.md) — configuration reference
---
## TASK-006 — SPA `*` wildcard redirect hides API 404s
**Severity:** Low
### Where found
`Docker/nginx.conf` — the catch-all `try_files $uri $uri/ /index.html` rule.
### Why this is needed
The SPA wildcard catches every unmatched path, including typos in API paths like `/api/jailss`. The browser receives a 200 with the SPA HTML instead of a 404, masking client-side bugs during development and making API integration harder to debug.
### Goal
Ensure `/api/**` paths that do not match any backend route return 404 from FastAPI, not 200 with HTML from nginx.
### What to do
1. In `nginx.conf`, ensure the `location /api/` block proxies to the backend and does **not** have a `try_files` fallback.
2. Verify that `location /api/` has higher priority than the catch-all `location /` block (nginx uses longest-prefix matching, so `/api/` takes precedence automatically).
3. Remove any `try_files` directives from the `/api/` location block.
### Possible traps and issues
- nginx `try_files` in a `location /` block will not affect `location /api/` as long as `/api/` is defined separately — verify the current config doesn't have an inherited `try_files`.
### Docs changes needed
- `Architekture.md` — document nginx routing rules.
### Doc references
- [Architekture.md](Architekture.md) — nginx / frontend serving
---
## TASK-007 — No rate limiting on the login endpoint
**Severity:** High