A secure password reset uses a long random single-use token with a limited lifetime, builds the link from a trusted domain, gives the same message whether or not the account exists, rate limits requests, notifies the owner, and ends existing sessions. Each piece closes a known takeover path.
Token rules
OWASP's Forgot Password cheat sheet lists these:
- Generate the token with a cryptographically secure random number generator and make it long enough to resist brute force.
- Tie each token to one user record.
- Give it a limited lifetime. OWASP says expire after an appropriate period and gives no number, so choose one that fits your users.
- Invalidate it once used.
- Store it securely. The page points to password storage guidance for how.
The link and the page
- Build the reset URL from a hard-coded value or a list of trusted domains, never from the Host header. A forged Host header can otherwise send victims a link to the attacker's domain.
- Use HTTPS.
- Set the Referrer Policy to no-referrer on the reset page, so the token does not leak to third-party resources.
Messages that do not leak accounts
Use one response for every case. OWASP's example: "If that email address is in our database, we will send you an email to reset your password." Keep response times and status codes consistent too, since differences reveal which accounts exist. A real-world example of the opposite is a user enumeration flaw in a framework's reset flow, which we covered in a past advisory post.
Abuse limits
Limit reset requests and token guesses per account, or use CAPTCHA. Otherwise attackers can flood a victim's inbox or guess short tokens.
After the reset
- Email the user that the password was changed. Never put the password in the email.
- End existing sessions, or ask the user whether to. After suspected compromise, do it automatically.
- Invalidate any other outstanding reset links and codes.
- Require re-authentication with a bound authenticator afterward, and do not use security questions.
- Where the account has MFA, do not let reset bypass it. See MFA recovery and fallback.
Test it
- Request a reset for a nonexistent email and compare the response to a real one.
- Try a used token and an expired token.
- Change the Host header and look at the link in the email.
- Confirm old sessions die after the reset.
Do not forget the support side. Agents sometimes have a button that sends or sets a reset on behalf of a user, and that button needs the same protection as the self-service flow. Require the agent to verify the person using your documented check, log who triggered the reset, and make sure it still sends the owner a notification. Attackers often target the human path because it is easier to talk past than code.
Quick check
Should reset links work for 24 hours?
OWASP gives no fixed number. Shorter is safer, so pick the shortest window your users can live with.
Is emailing a new password acceptable?
No. OWASP says never include the password in the email. Send a link to set one.
Sources
Last reviewed: 19 October 2026.