Topic 10 · Deep Dive

10.4 Password Reset Flows and Recovery Risks

The Reset Pipeline Done Right

A recovery link is an unauthenticated path to administrative control of an account, so treat it like a privileged endpoint. The healthy sequence is: the user submits an identifier; the server generates a high-entropy random token, stores only its hash next to the account, emails a link, and marks the token as used the moment it redeems. The token should be opaque, single-use, short-lived -- fifteen minutes is a common budget -- and bound to the account and, ideally, to the session and user agent that requested it. Redeeming it must invalidate every outstanding token and, for high-value accounts, every active session, otherwise an attacker's already-stolen cookie survives their own password change.

Enumeration Leaks Through Response Text

The most common defect is also the cheapest to fix: differential responses. "No account with that email exists" confirms which addresses are unregistered; "check your inbox" confirms which are registered, and different HTTP statuses, redirect targets, or a half-second of extra bcrypt time say the same thing louder. The cure is uniformity -- always return the same neutral sentence and the same status, always send the same latency, and let the email itself carry the branch: registered users get a reset link, unregistered ones get "someone requested a reset for an address you do not have; here is how to review it". Rate limit per identifier and per source address, since enumeration is otherwise free at script speed.

Token and Channel Weaknesses

Tokens fail on the edges. Derived from timestamps or account IDs they become predictable; delivered inside the URL they leak through the Referer header, proxy logs, and browser history, which is why the modern pattern is an unauthenticated confirmation page that POSTs the token rather than a GET that loads the app logged-in. Host-header or password-reset poisoning lets an attacker rewrite the link domain so the victim's token arrives at their server. Long expiry and reuse turn one intercepted mail into permanent access. The OWASP Authentication Cheat Sheet and the OWASP Application Security Verification Standard cover these requirements explicitly.

Recovery Bypasses and the Human Layer

Security questions are a searchable database: mother's maiden name, street you grew up on, first pet -- all corpus material from breach dumps and public social posts, and rarely verified. Retire them in favor of authenticator-based or passkey recovery, pre-registered trusted devices, and time-delayed changes that notify the old address. Assume support staff are the real bypass target, so give agents no reset authority without a second factor on file, and lock account recovery behind an identity step that cannot be answered from a spreadsheet.

Architecture Diagram

reset pipeline and its leaks reset request identifier only single-use token 15-min expiry, hashed at rest email link set new password enumeration via response text fix: same reply either way security-question bypass answers sit in breach dumps token in a GET leaks via Referer, logs, and history host header poisoning can mail the link to an attacker domain uniform replies, opaque bound tokens, revoke all sessions on change
The pipeline is short; both realistic failures are informational -- a response that confirms accounts and a recovery question that is really a public fact.

Key Takeaways

« Back to Topic 10« 10.3 / 10.5 »