# Password Reset

## Overview

This page contains recommendations for the implementation of password reset functionality.

## General

<div align="left"><img src="https://1795604890-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaH8j4W1MtabOUlUc8Trn%2Fuploads%2Fgit-blob-b41291c03c4de901e1f0faa235c5ad68838b2947%2Ftype-base-icon.svg?alt=media" alt=""></div>

* Implement a password reset in one of the following ways:
  * [Password reset based on a URL token](#password-reset-based-on-a-url-token)
  * [Password reset based on a one-time password](#password-reset-based-on-a-one-time-password)
* During password reset do **not** indicate if a user with entered data exists or not. Ask for a username/email address/phone number/etc. and inform the a that if there is a user with the data entered, reset recommendations will be sent to them via the appropriate communication channel.
* Only block an old password after a user has successfully passed the password reset step.
* Do **not** automatically sign a user in. Once a user sets their new password, log out a user and send them to a usual login mechanism (with multi-factor authentication, if enabled).
* Terminate all active sessions after the password reset. You can explicitly ask a user if they want to invalidate all of their existing sessions.
* During password reset, request at least the following data:
  * New password.
  * Confirmation of the new password.
* Link a random token (or one-time password) to an individual user in a database.
* Do **not** reveal a current password in any way during the password reset.
* Do **not** reveal a random token (or one-time password) in any way during the password reset.
* Log successful and failed password reset attempts, see the [Logging and Monitoring](https://0xn3va.gitbook.io/application-security-handbook/web-application/logging-and-monitoring) page.
* Comply with requirements from the [Error and Exception Handling](https://0xn3va.gitbook.io/application-security-handbook/web-application/error-and-exception-handling) page.

<div align="left"><img src="https://1795604890-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaH8j4W1MtabOUlUc8Trn%2Fuploads%2Fgit-blob-4b891edb8f5a26f439d757f90613f83f54c2107c%2Ftype-advanced-icon.svg?alt=media" alt=""></div>

* Implement a password reset in the following way:
  * [Password reset based on a time-based one-time password](#password-reset-based-on-a-time-based-one-time-password)

## Password reset based on a URL token

<div align="left"><img src="https://1795604890-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaH8j4W1MtabOUlUc8Trn%2Fuploads%2Fgit-blob-b41291c03c4de901e1f0faa235c5ad68838b2947%2Ftype-base-icon.svg?alt=media" alt=""></div>

* Send a password reset URL to a user and pass a random token in the query string of the URL. For example:

  ```
  https://website.local/account/password/reset?token=GiOzXAwlZ17NsW4CkVV8MQXtiQN9cWiY
  ```
* Generate a random token using a cryptographically strong random generator, see the [Cryptography: Random Generators](https://0xn3va.gitbook.io/application-security-handbook/web-application/cryptography/random-generators) page.
* Use random tokens of length 32+ bytes.
* Set a short expiration time for a random token (\~ 24 hours).
* Use a random token once. Delete a random token or transfer it to a final status that prohibits reusing.
* Do **not** rely on the `Host` HTTP header while creating the reset URLs to avoid the [Host Header Injection](https://owasp.org/www-project-web-security-testing-guide/stable/4-Web_Application_Security_Testing/07-Input_Validation_Testing/17-Testing_for_Host_Header_Injection) attack. Either hardcode the URL or validate against a list of trusted domains using an allow list.
* Add the [Referrer-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy) HTTP header with the `noreferrer` value to the reset password page in order to avoid [referrer leakage](https://portswigger.net/kb/issues/00500400_cross-domain-referer-leakage).

## Password reset based on a one-time password

<div align="left"><img src="https://1795604890-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaH8j4W1MtabOUlUc8Trn%2Fuploads%2Fgit-blob-b41291c03c4de901e1f0faa235c5ad68838b2947%2Ftype-base-icon.svg?alt=media" alt=""></div>

* Send a one-time password to a user for confirmation of the password reset.
* Comply with the requirements from the [Authentication: One Time Password (OTP)](https://0xn3va.gitbook.io/application-security-handbook/web-application/authentication/one-time-password-otp) page.

## Password reset based on a time-based one-time password

<div align="left"><img src="https://1795604890-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaH8j4W1MtabOUlUc8Trn%2Fuploads%2Fgit-blob-4b891edb8f5a26f439d757f90613f83f54c2107c%2Ftype-advanced-icon.svg?alt=media" alt=""></div>

* Use a time-based one-time password generated on the user side for confirmation of the password reset.
* Comply with the requirements from the [Authentication: One Time Password (OTP)](https://0xn3va.gitbook.io/application-security-handbook/web-application/authentication/one-time-password-otp) page.

## References

* [OWASP Cheat Sheet Series: Forgot Password Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Forgot_Password_Cheat_Sheet.html)
