security: harden JWT auth with session binding, CSP headers, and sessionStorage

- Reduce access_token_ttl from 900s to 300s (5 min) to shrink XSS exploit window
- Add session_id claim to JWT tokens tied to browser session (X-Session-Id header)
- Flask middleware validates session_id matches header on every request
- CSP headers: default-src/script-src 'self', no unsafe-inline/eval, frame-ancestors none
- X-Content-Type-Options: nosniff on all responses
- Move refresh token from localStorage to sessionStorage (tab-scoped, cleared on close)
- Timing-safe password verification (dummy Argon2id for unknown users)
- WebSocket auth also validates session_id header
- Add 5 session_id tests and 3 CSP header tests
This commit is contained in:
2026-07-24 02:51:54 +00:00
parent 56b200d233
commit a365059976
13 changed files with 317 additions and 96 deletions
+2 -1
View File
@@ -396,7 +396,8 @@ async def _handle_ws(request: web.Request) -> web.Response:
{"ok": False, "error": "authentication required"}, status=401
)
payload = validate_token(token_param, token_type="access")
session_header = request.headers.get("X-Session-Id")
payload = validate_token(token_param, token_type="access", session_id=session_header)
if payload is None:
return web.json_response({"ok": False, "error": "unauthorized"}, status=401)