Password Reset Security Review: Tokens, Enumeration, and Expiry
Reset token issuance and atomic redemption
Treat reset request as pre-authentication capability issuance. Compare registered and unknown account requests under same conditions: external message and observable timing should remain uniform, while internal monitoring may retain safe outcome category. Rate controls protect mail or SMS delivery but cannot expose whether recipient exists. Never log raw token, password, or reset URL.
Issue opaque cryptographically random value, retain protected representation, bind it to one account and reset purpose, set expiry, and consume it atomically with password change. Do not trust an account identifier added to link; derive account only from validated token record. Test an old link, second redemption, concurrent double redemption, token copied to another account, and reset followed by replay of an old session.
Expected output is uniform request response, one successful redemption at most, intended session invalidation, and notification after change. Evidence includes paired captures, storage design, transaction result, controlled expiry result, and session replay response. Repair by hashing or otherwise protecting stored token, adding unique one-use state, and moving consumption into transaction. Support-assisted reset is separate identity-proofing process with its own audit and escalation rules, not fallback for failed automated token.
Delivery links create their own exposure surface. Use HTTPS, avoid third-party content on reset page, and prevent token from entering analytics or referrer data. Request rate control should cover sender cost and recipient disruption; a valid account must not be mail-bombed by repeated reset requests. Test request after account deletion or email change and define expected safe response. Password change must follow normal password policy and compromise checks, not accept any replacement because token is valid.
Issue an account-bound reset capability
Password reset begins before authentication and must not reveal account existence. Submit same-shaped requests for a registered email and a synthetic unknown email. External status, message, and observable timing should follow one designed pattern. Internal monitoring may record safe outcome categories, but raw email, reset URL, password, and token must not enter logs. Rate controls protect delivery cost and recipient disruption; they cannot turn a response into an account-existence oracle.
Create reset capability from cryptographically strong random value. Send opaque value only through intended protected delivery channel, retain a protected representation server-side, bind it to one account and reset purpose, set short policy-selected expiry, and consume it atomically with password change. Do not trust an account ID appended to link; derive account from validated reset record. Reset page needs HTTPS, restrictive referrer behavior, no third-party content that can receive URL, and no token displayed after submission.
Single-use and expiry cases
Use a controlled account to request a link, redeem it once, then repeat redemption. Expected result is one password change at most, a generic safe response for replay, and no new session unless application explicitly issues one after normal authentication. Test expired token using controlled time, token copied to another account, two concurrent redemption requests, reset request after account deletion, and reset request after email change. Verify transaction leaves consistent state: no consumed token with unchanged password, and no changed password with reusable token after a server error.
Password validation remains normal authentication policy after token validation. Check length and breached-secret policy if deployed; a valid reset token is not permission to choose weak replacement. On success, invalidate reset capability, record a PII-minimized security event, send a post-reset notice without password or raw link, and invalidate sessions according to documented account policy. Replay old browser session and API token where applicable to prove aftermath.
Support reset and closure
Support-assisted reset is a separate identity-proofing process, not fallback for a failed link. It needs case ownership, evidence category, approval boundary, and audit result. Test that support cannot set a password, view a raw reset token, or skip a second approval where policy requires it. For automated flow, evidence includes paired enumeration captures, protected-token design, entropy source review, expiry result, redemption transaction result, notification outcome, and session replay result.
Remediate enumeration with uniform external handling, token issues with protected storage and atomic one-use state, and delivery exposure with strict URL handling. Closure repeats unknown-account request, concurrent redemption, expired link, account-substitution, and pre-reset-session replay. A short migration exception identifies route, delivery consumer, end date, and compensating transport control; it never permits a reusable bearer reset token.
Reset-token redemption record
| Reset case | Owner | Evidence | Expected result | Observed result / status | Exception | Closure |
|---|---|---|---|---|---|---|
Concurrent redemption of one token for synthetic account acct-reset-09 | Authentication owner | Paired capture PR-144; transaction trace; token-state and session-replay results | One password change; token consumed atomically; old sessions rejected | 1 success, 1 generic denial; token consumed; 3 old sessions denied — closed | None | Expiry, account-substitution, and unknown-account response retests passed 2026-06-19 |