fix(auth): address SA4 review findings (WS epoch check, commit ordering, verify guard)
Adversarial re-review of the session-epoch work surfaced: - WS auth (messages_ws) skipped the epoch check, so a revoked-but-unexpired cookie could still open the live push channel after a reset/logout-others. Now mirrors current_user: loads the user once, rejects a stale-epoch cookie before connecting. - set_password + logout_others re-stamped the cookie BEFORE db.commit(); a failed commit would strand the current session at a newer epoch than the DB and wrongly 401 it. Commit first, then re-stamp. - Welcome verify effect could double-POST the single-use token (StrictMode/remount) and flip the banner to a false 'invalid'. Fire-once useRef guard. Left as-is (low value, documented): the Plex image proxy authenticates without a DB load / epoch check (poster/art fetches only); adding one would cost a DB hit per image.
This commit is contained in:
parent
95d1549570
commit
07dba4da9e
3 changed files with 20 additions and 7 deletions
|
|
@ -381,7 +381,13 @@ async def messages_ws(ws: WebSocket) -> None:
|
|||
return
|
||||
db = SessionLocal()
|
||||
try:
|
||||
ok = is_messageable_user(db.get(User, uid))
|
||||
user = db.get(User, uid)
|
||||
# SA4: honour server-side session revocation on the live channel too — reject a cookie whose
|
||||
# recorded epoch is behind the account's current one (mirrors current_user). Without this a
|
||||
# copied cookie could keep receiving pushes after a password reset / "log out everywhere".
|
||||
epochs = sess.get("epochs") or {}
|
||||
epoch_ok = user is not None and int(epochs.get(str(uid), 0)) == (user.session_epoch or 0)
|
||||
ok = epoch_ok and is_messageable_user(user)
|
||||
finally:
|
||||
db.close()
|
||||
if not ok:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue