fix(auth): protect setup and expire sessions
This commit is contained in:
@@ -5,7 +5,7 @@ import hashlib
|
||||
import hmac
|
||||
import json
|
||||
import secrets
|
||||
from datetime import UTC, datetime
|
||||
from datetime import UTC, datetime, timedelta
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
@@ -42,9 +42,24 @@ def _session_key(master_key_file: Path) -> bytes:
|
||||
return hashlib.sha256(b"backup-tool-session\0" + master_key_file.read_bytes()).digest()
|
||||
|
||||
|
||||
def sign_session(user_id: str, csrf: str, master_key_file: Path) -> str:
|
||||
def sign_session(
|
||||
user_id: str,
|
||||
csrf: str,
|
||||
master_key_file: Path,
|
||||
*,
|
||||
expires_at: datetime | None = None,
|
||||
session_id: str | None = None,
|
||||
) -> str:
|
||||
issued_at = datetime.now(UTC)
|
||||
expires_at = expires_at or issued_at.replace(microsecond=0) + timedelta(hours=8)
|
||||
payload = json.dumps(
|
||||
{"sub": user_id, "csrf": csrf, "iat": datetime.now(UTC).isoformat()},
|
||||
{
|
||||
"sub": user_id,
|
||||
"csrf": csrf,
|
||||
"iat": issued_at.isoformat(),
|
||||
"exp": expires_at.astimezone(UTC).isoformat(),
|
||||
"sid": session_id or secrets.token_urlsafe(24),
|
||||
},
|
||||
separators=(",", ":"),
|
||||
sort_keys=True,
|
||||
).encode()
|
||||
@@ -65,7 +80,13 @@ def verify_session(value: str, master_key_file: Path) -> dict[str, Any] | None:
|
||||
return None
|
||||
padded = encoded + "=" * (-len(encoded) % 4)
|
||||
decoded = json.loads(base64.urlsafe_b64decode(padded))
|
||||
if not isinstance(decoded, dict) or not isinstance(decoded.get("sub"), str):
|
||||
if (
|
||||
not isinstance(decoded, dict)
|
||||
or not isinstance(decoded.get("sub"), str)
|
||||
or not isinstance(decoded.get("sid"), str)
|
||||
or not isinstance(decoded.get("exp"), str)
|
||||
or datetime.fromisoformat(decoded["exp"]).astimezone(UTC) <= datetime.now(UTC)
|
||||
):
|
||||
return None
|
||||
return decoded
|
||||
except (ValueError, json.JSONDecodeError, UnicodeDecodeError):
|
||||
|
||||
Reference in New Issue
Block a user