CodePark/ questions / Authentication vs authorization
START PRACTICINGPRACTICE
Backend question · Auth & security › Authentication vs authorization

Design a secure "forgot password" flow for an API. What does the token look like, how is it stored, and what happens after the reset?

Step 1: the request. The user submits their email. They always get the same response, whether or not the account exists. If the account exists, the server:

  • Makes a long random token with a CSPRNG (a cryptographically secure random number generator), for example crypto.randomBytes(32).
  • Stores only a hash of the token, with the user id and a short expiry time.
  • Emails an HTTPS link that contains the token.

Step 2: the reset. When the user opens the link, the server:

  • Hashes the submitted token and looks it up.
  • Checks that it has not expired.
  • Lets the user set a new password.
  • Deletes the token, so it works only once.

Step 3: after the reset. End all existing sessions and refresh tokens. Then email the user to tell them the password changed.

What to avoid:

  • Don't put user ids or predictable values in the token.
  • Don't log the link.
  • Don't build the link from the request's Host header. An attacker can change that header, so the email would send the token to the attacker's own domain. Build the link from configuration instead.
  • The response is the same whether or not the account exists.
  • The token is random from a CSPRNG, stored as a hash, short-lived and single use.
  • After the reset, end all sessions and refresh tokens.
  • Email the user to tell them the password changed.
  • Build reset links from configuration, not from the Host header.