Insecure Password Reset Tokens

A password reset token is the secret a web application issues (usually by email or SMS) to prove that the person requesting a password change controls the account’s recovery channel. Because the reset flow is an alternate authentication path, its security must be at least as strong as the primary login — and it is a frequent weak point that yields full account takeover. OWASP classifies flaws here under A07:2021 – Identification and Authentication Failures.

Failure modes

Predictable token generation

Tokens built from known or guessable inputs — timestamps, usernames, email addresses, or simple hashes of them — let an attacker synthesize a valid token for an arbitrary account without accessing the recovery channel. OWASP WSTG is explicit: tokens must come from a CSPRNG with at least 128 bits of entropy, and must never be derived from known values such as md5($email) or a GUID backed by a non-random PRNG. Time-based tokens are a special case: if two reset requests are processed in the same second, they may receive identical tokens, so an attacker who triggers a victim reset and a self reset in parallel can reuse their own token against the victim.

Token leakage through the application

Even a well-generated token is useless to defend if the application discloses it in an API response. Excessive-data-exposure flaws (OWASP API3) in user-object endpoints can return the reset token alongside other sensitive fields — email, admin flags, password hashes — letting any authenticated (or unauthenticated) caller read a freshly-issued token for any user and complete the reset themselves. This chains naturally with user-ID enumeration (sequential integers) for full-account-takeover of every account on the platform, including administrators.

Missing validation and lifecycle controls

  • Token not checked at all — the reset endpoint trusts a hidden username field, so submitting a new password for any account works regardless of the token (PortSwigger “broken logic” lab).
  • Token not invalidated after use — a used link becomes a persistent backdoor.
  • No expiry — tokens that live forever extend the attack window indefinitely.
  • No rate limiting / lockout — short tokens (6-digit SMS codes, ~20 bits) become brute-forceable.
  • Host-header poisoning — if the reset link’s domain is built from the request’s Host header, an attacker can poison the emailed link so the token is delivered to a server they control (see http and PortSwigger’s password-reset-poisoning material).
  • Referer leakage — third-party content on the reset page can carry the token off-site in the Referer header.

Exploitation pattern

A typical chain observed in real applications and cyber ranges:

  1. Enumerate user IDs on an endpoint that returns full user objects (a broken object-level authorization / IDOR flaw).
  2. Note that the response includes password_reset_token (or the endpoint is unauthenticated and leaks users + salts + hashes).
  3. Request a password reset for the target’s email.
  4. Re-query the endpoint to read the freshly minted token — or, when the token is time-derived ($EMAIL-$DATE-$HOUR), synthesize it from the Date response header.
  5. Submit the token with a new password; log in as the victim.

Remediation

  • Generate tokens with a CSPRNG, ≥128 bits, unique per user and per reset attempt; never derive them from email, username, or timestamp.
  • Return no more data than the page needs from user-object endpoints — never reset tokens, password hashes, salts, or admin flags; scope responses to the currently authenticated user.
  • Invalidate tokens on first use and expire them quickly (minutes, not days); store only a hash of the token server-side.
  • Rate-limit and CAPTCHA the reset request and token submission endpoints.
  • Build reset links from a fixed, configured domain — never from the Host header.
  • Require re-authentication before changing the account’s primary identifier (email/phone), so a hijacked session can’t redirect the recovery channel.

Sources

Related: xss-attacks, http, burp-suite