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:
+11
-5
@@ -289,10 +289,10 @@ def validate_token(
|
||||
Args:
|
||||
token_string: The JWT token string.
|
||||
token_type: Expected token type ("access" or "refresh").
|
||||
session_id: If provided, must match the ``session_id`` claim in the
|
||||
token payload. Acts as session binding — prevents a stolen token
|
||||
from being used by an attacker who doesn't also possess the
|
||||
matching session ID.
|
||||
session_id: Must match the ``session_id`` claim in the token payload.
|
||||
Required for access tokens — prevents a stolen token from being
|
||||
usable without the originating session. Ignored for refresh tokens
|
||||
which carry no ``session_id`` claim.
|
||||
|
||||
Returns:
|
||||
Payload dict including permissions, or None if invalid/blacklisted.
|
||||
@@ -302,7 +302,13 @@ def validate_token(
|
||||
return None
|
||||
if payload.get("type") != token_type:
|
||||
return None
|
||||
if session_id and payload.get("session_id") != session_id:
|
||||
if token_type == "access" and session_id != payload.get("session_id"):
|
||||
return None
|
||||
if (
|
||||
token_type != "access"
|
||||
and session_id
|
||||
and payload.get("session_id") != session_id
|
||||
):
|
||||
return None
|
||||
|
||||
jti = payload.get("jti")
|
||||
|
||||
Reference in New Issue
Block a user