Difference between revisions of "Forgot Password Cheat Sheet"

From OWASP
Jump to: navigation, search
m (Authors and Primary Editors)
m
(9 intermediate revisions by 5 users not shown)
Line 6: Line 6:
  
 
There is no industry standard for implementing a Forgot Password feature. The result is that you see applications forcing users to jump through myriad hoops involving emails, special URLs, temporary passwords, personal security questions, and so on. With some applications you can recover your existing password. In others you have to reset it to a new value.
 
There is no industry standard for implementing a Forgot Password feature. The result is that you see applications forcing users to jump through myriad hoops involving emails, special URLs, temporary passwords, personal security questions, and so on. With some applications you can recover your existing password. In others you have to reset it to a new value.
 
The recommendations presented here for implementing Forgot Password are most appropriate for organizations that have a business relationship with users. Web applications that target the general public (social networking, free email sites, etc.) are fundamentally different and some concepts presented may not be feasible in those situations.
 
  
 
= Steps  =
 
= Steps  =
  
== Step 1) Gather Identity Data ==
+
== Step 1) Gather Identity Data or Security Questions ==
  
The first page of a secure Forgot Password feature asks the user for multiple pieces of hard data. A single HTML form should be used for all of the inputs.
+
The first page of a secure Forgot Password feature asks the user for multiple pieces of hard data that should have been previously collected (generally when the user first registers). Steps for this are detailed in the [[Choosing and Using Security Questions Cheat Sheet]].
  
A minimum of three inputs is recommended, but the more you require, the more secure it will be. One of the inputs, preferably listed first, should be the email address. Others can be selected depending on the nature of the data available to the application. Examples include:
+
At a minimum, you should have collected some data that will allow you to send the password reset information to some out-of-band side-channel, such as a (possibly different) email address or an SMS text number, etc. to be used in Step 3.
 
+
* email address
+
* last name
+
* date of birth
+
* account number
+
* customer number
+
* social security number
+
* zip code for address on file
+
* street number for address on file
+
 
+
For enhanced security, you may wish to consider asking the user for their email address first and then send an email that takes them to a private page that requests the other 2 (or more) identity factors. That way the email itself isn’t that useful because they still have to answer a bunch of ‘secret’ questions after they get to the landing page.
+
  
 
== Step 2) Verify Security Questions ==
 
== Step 2) Verify Security Questions ==
Line 33: Line 20:
  
 
Do not provide a drop-down list for the user to select the questions he wants to answer. Avoid sending the username as a parameter (hidden or otherwise) when the form on this page is submitted. The username should be stored in the server-side session where it can be retrieved as needed.
 
Do not provide a drop-down list for the user to select the questions he wants to answer. Avoid sending the username as a parameter (hidden or otherwise) when the form on this page is submitted. The username should be stored in the server-side session where it can be retrieved as needed.
 +
 +
Because users' security questions / answers generally contains much less entropy than a well-chosen password (how many likely answers are there to the typical "What's your favorite sports team?" or "In what city where you born?" security questions anyway?), make sure you limit the number of guesses attempted and if some threshold is exceeded for that user (say 3 to 5), lock out the user's account for some reasonable duration (say at least 5 minutes) and send an email (or SMS text, if that is your side channel of choice; see #3, below) to mitigate attempts by hackers to guess the questions and reset the user's password. (It is not unreasonable to think that a user's email account may have already been compromised.) Using something like the [[OWASP AppSensor Project]] to implement this should make adding this behavior somewhat easier, assuming you already have the ability to temporarily lock out a user's account.
  
 
==  Step 3) Send a Token Over a Side-Channel ==
 
==  Step 3) Send a Token Over a Side-Channel ==
  
After step 2, email or SMS the user a randomly-generated code having 8 or more characters. This introduces an “out of band” communication channel and would be extremely tough for a hacker to overcome. If the bad guy has somehow managed to successfully get past steps 1 and 2, he is unlikely to have compromised the side channel.  
+
After step 2, lock out the user's account immediately. Then email or SMS the user a randomly-generated code having 8 or more characters. This introduces an “out-of-band” communication channel and adds defense-in-depth as it is another barrier for a hacker to overcome. If the bad guy has somehow managed to successfully get past steps 1 and 2, he is unlikely to have compromised the side-channel.  It is also a good idea to have the random code which your system generates to only have a limited validity period, say no more than 20 minutes or so. That way if the user doesn't get around to checking their email and their email account is later compromised, the random token used to reset the password would no longer be valid if the user never reset their password and the "reset password" token was discovered by an attacker. Of course, by all means, once a user's password has been reset, the randomly-generated token should no longer be valid.
  
 
== Step 4) Allow user to change password ==
 
== Step 4) Allow user to change password ==
Line 43: Line 32:
  
 
= Related Articles  =
 
= Related Articles  =
 +
FishNet Security White Paper - [http://www.fishnetsecurity.com/sites/default/files/media/10WP0003_BestPractices_SecureForgotPassword%5B1%5D_0.pdf Best Practices for a Secure "Forgot Password" Feature]
  
FishNet Security White Paper - [http://www.fishnetsecurity.com/Resource_/PageResource/White_Papers/FishNetSecurity_SecureForgotPassword.pdf Best Practices for a Secure "Forgot Password" Feature]
+
= Authors and Primary Editors  =
  
 +
Dave Ferguson - gmdavef[at]gmail com<br/>
 +
Jim Manico - jim[at]owasp.org<br/>
 +
Kevin Wall - kevin.w.wall[at]gmail com
 +
 +
= Other Cheatsheets =
 
{{Cheatsheet_Navigation}}
 
{{Cheatsheet_Navigation}}
 
= Authors and Primary Editors  =
 
 
Dave Ferguson - Dave.Ferguson[at]fishnetsecurity com<br/>
 
Jim Manico - jim[at]owasp.org
 
  
 
[[Category:Cheatsheets]]
 
[[Category:Cheatsheets]]

Revision as of 04:59, 24 January 2013

Contents

Introduction

This article provides a simple model to follow when implementing a "forgot password" web application feature.

The Problem

There is no industry standard for implementing a Forgot Password feature. The result is that you see applications forcing users to jump through myriad hoops involving emails, special URLs, temporary passwords, personal security questions, and so on. With some applications you can recover your existing password. In others you have to reset it to a new value.

Steps

Step 1) Gather Identity Data or Security Questions

The first page of a secure Forgot Password feature asks the user for multiple pieces of hard data that should have been previously collected (generally when the user first registers). Steps for this are detailed in the Choosing and Using Security Questions Cheat Sheet.

At a minimum, you should have collected some data that will allow you to send the password reset information to some out-of-band side-channel, such as a (possibly different) email address or an SMS text number, etc. to be used in Step 3.

Step 2) Verify Security Questions

After the form on Step 1 is submitted, the application verifies that each piece of data is correct for the given username. If anything is incorrect, or if the username is not recognized, the second page displays a generic error message such as “Sorry, invalid data”. If all submitted data is correct, Step 2 should display at least two of the user’s pre-established personal security questions, along with input fields for the answers. It’s important that the answer fields are part of a single HTML form.

Do not provide a drop-down list for the user to select the questions he wants to answer. Avoid sending the username as a parameter (hidden or otherwise) when the form on this page is submitted. The username should be stored in the server-side session where it can be retrieved as needed.

Because users' security questions / answers generally contains much less entropy than a well-chosen password (how many likely answers are there to the typical "What's your favorite sports team?" or "In what city where you born?" security questions anyway?), make sure you limit the number of guesses attempted and if some threshold is exceeded for that user (say 3 to 5), lock out the user's account for some reasonable duration (say at least 5 minutes) and send an email (or SMS text, if that is your side channel of choice; see #3, below) to mitigate attempts by hackers to guess the questions and reset the user's password. (It is not unreasonable to think that a user's email account may have already been compromised.) Using something like the OWASP AppSensor Project to implement this should make adding this behavior somewhat easier, assuming you already have the ability to temporarily lock out a user's account.

Step 3) Send a Token Over a Side-Channel

After step 2, lock out the user's account immediately. Then email or SMS the user a randomly-generated code having 8 or more characters. This introduces an “out-of-band” communication channel and adds defense-in-depth as it is another barrier for a hacker to overcome. If the bad guy has somehow managed to successfully get past steps 1 and 2, he is unlikely to have compromised the side-channel. It is also a good idea to have the random code which your system generates to only have a limited validity period, say no more than 20 minutes or so. That way if the user doesn't get around to checking their email and their email account is later compromised, the random token used to reset the password would no longer be valid if the user never reset their password and the "reset password" token was discovered by an attacker. Of course, by all means, once a user's password has been reset, the randomly-generated token should no longer be valid.

Step 4) Allow user to change password

Step 4 requires input of the code sent in step 3 and allows the user to reset his password. Display a simple HTML form with one input field for the code, one for the new password, and one to confirm the new password. Verify the correct code is provided and be sure to enforce all password complexity requirements that exist in other areas of the application. As before, avoid sending the username as a parameter when the form is submitted. Finally, it's critical to have a check to prevent a user from accessing this last step without first completing steps 1 and 2 correctly. Otherwise, a forced browsing attack may be possible.

Related Articles

FishNet Security White Paper - Best Practices for a Secure "Forgot Password" Feature

Authors and Primary Editors

Dave Ferguson - gmdavef[at]gmail com
Jim Manico - jim[at]owasp.org
Kevin Wall - kevin.w.wall[at]gmail com

Other Cheatsheets

OWASP Cheat Sheets Project Homepage

Developer Cheat Sheets (Builder)

Assessment Cheat Sheets (Breaker)

Mobile Cheat Sheets

OpSec Cheat Sheets (Defender)

Draft Cheat Sheets