enforce mandatory X-Session-Id header for access token validation

Session binding was bypassable: if the X-Session-Id header was absent,
validate_token skipped the check entirely, allowing a stolen JWT to be
used without the originating session.

Server-side: reject 401 early in Flask middleware and daemon WebSocket
handler when X-Session-Id is missing, before calling validate_token.
Updated validate_token to always enforce session_id matching for access
tokens (refresh tokens are unaffected as they carry no session_id claim).

Frontend: removed dead if (stored.session_id) guards in api.js since
the header is now always required. Added X-Session-Id to logout request
headers and always store session_id on login/refresh.
This commit is contained in:
2026-07-30 22:55:16 +00:00
parent 43b44ad340
commit b69ca330f4
6 changed files with 39 additions and 28 deletions
+2
View File
@@ -397,6 +397,8 @@ async def _handle_ws(request: web.Request) -> web.Response:
)
session_header = request.headers.get("X-Session-Id")
if not session_header:
return web.json_response({"ok": False, "error": "unauthorized"}, status=401)
payload = validate_token(
token_param, token_type="access", session_id=session_header
)