TASK-025: Remove HMAC bypass in unwrap_session_token

- Remove the early-return branch that skipped HMAC verification for unsigned tokens
- Raise ValueError if the signature separator is absent
- Update unwrap_session_token docstring to reflect mandatory signing requirement
- Add comprehensive session token signing documentation to Backend-Development.md
- Document the session token format, signing/verification pattern, and security rationale

All tokens must now carry a valid HMAC-SHA256 signature. Tokens without a
signature are rejected immediately. This removes the vulnerability where an
attacker with database access could bypass the HMAC layer by using raw tokens.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-04-26 15:02:02 +02:00
parent c2348d7075
commit a768a2d303
2 changed files with 72 additions and 3 deletions

View File

@@ -44,11 +44,21 @@ def sign_session_token(token: str, secret: str) -> str:
def unwrap_session_token(token: str, secret: str) -> str:
"""Verify and return the raw token from a signed session token.
If the token has no signature component, it is returned unchanged. This
preserves compatibility with existing raw session tokens stored in the DB.
All tokens must carry a valid HMAC-SHA256 signature. Tokens without
a signature are rejected.
Args:
token: The signed session token in format "raw_token.signature".
secret: The HMAC secret used to verify the signature.
Returns:
The raw token component.
Raises:
ValueError: If the token lacks a signature or the signature is invalid.
"""
if SESSION_TOKEN_SIGNATURE_SEPARATOR not in token:
return token
raise ValueError("Invalid session token.")
raw_token, signature = token.rsplit(SESSION_TOKEN_SIGNATURE_SEPARATOR, 1)
expected_signature = _session_token_signature(raw_token, secret)