fix: close refresh token session binding bypass
Add require_session parameter to validate_token to enforce session_id matching for refresh operations. Attacker with stolen refresh token can no longer bypass session binding by omitting session_id from request. Also adds backend guard against deleting builtin admin user (was only blocked at Flask blueprint layer), and removes unused _ALL_RW variable.
This commit is contained in:
@@ -44,7 +44,6 @@ from lib.auth import (
|
||||
validate_token,
|
||||
)
|
||||
from lib.auth_users import (
|
||||
ALL_SUBSYSTEMS,
|
||||
create_user,
|
||||
delete_user,
|
||||
get_user,
|
||||
@@ -70,8 +69,6 @@ from lib.webauthn import (
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_ALL_RW = {sub: "rw" for sub in ALL_SUBSYSTEMS}
|
||||
|
||||
|
||||
def _clear_refresh_token_after_rotation(username: str) -> None:
|
||||
"""Remove the user's entry from refresh_tokens after a successful refresh rotation."""
|
||||
@@ -176,7 +173,12 @@ def auth_refresh(_request: Any, body: Any) -> dict[str, Any]:
|
||||
raise ValueError("refresh_token is required")
|
||||
|
||||
session_id = body.get("session_id")
|
||||
payload = validate_token(refresh_token, token_type="refresh", session_id=session_id)
|
||||
if not session_id:
|
||||
raise ValueError("session_id is required")
|
||||
|
||||
payload = validate_token(
|
||||
refresh_token, token_type="refresh", session_id=session_id, require_session=True
|
||||
)
|
||||
if payload is None:
|
||||
raise ValueError("Invalid or expired refresh token")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user