fix(auth): make login-approval consume atomic to close a TOCTOU (LC-601) #557
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/LC-601-login-approval-consume-toctou"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Closes a TOCTOU in the LC-587 suspicious-login approval flow found in post-merge review.
login_approval::verifyread the pending challenge (SELECT ... WHEREconsumed_at IS NULL), compared the submitted code, then consumed the row with an unconditional UPDATE whose result was ignored. Two concurrent correct-code submits (a double-clicked Approve, two tabs) could both pass the read and the comparison and both mint a session, breaking the single-use invariant.Fix
db::auth::consume_login_approvalguards its UPDATE withAND consumed_at IS NULLand returns the rows affected, making it the atomic winner-take-all gate.verifymints a session only when its own consume reported one row (Ok(1)); a racing second submit consumes zero rows and getsInvalidinstead of a second session.Impact / severity
Low: the trigger requires the valid emailed code, so it is a double-submit by the legitimate user, not an attacker bypass. But it violated the single-use invariant (two sessions from one challenge), so it is worth fixing.
Tests
New
db_login_approval::consume_is_conditional_single_winner: first consume returns 1, a second returns 0, and averifywith the correct code after the row is consumed isInvalid. Green onfmt+clippy -D warnings(standalone + saas, all targets) + the login-approval tests.#LC-601