Friday, April 25, 2014

Implementing Forgot Password with Email

It turns out that application developers sometimes need to implement a forgot password feature but don't have much identity data about the users in the system.  Neither can they always be so flexible as to require users to establish personal security questions.  These things are a key part of my forgot password security recommendations.  But the reality is that sometimes you don't have any information about a user except their username and email address.  Heck, sometimes email address IS the username.

In this type of situation, implementing a secure forgot password feature is challenging.  Sending a password reset link via email is probably the best option (barring a non-automated solution where users call customer support).  So here I will offer up some specific ideas on how to secure the process when using email.

  1. When a user invokes the forgot password process, don't say anything about whether the username entered was recognized or not.  It should simply display a generic message such as: "Thank you. If the username you provided is valid, we will send you an email with instructions on how to reset your password".
  2. Along with the above, don't show the email address where the email was sent.  It might give legitimate users a warm, fuzzy feeling but it definitely helps attackers in a number of scenarios.
  3. The password reset link in the email message should incorporate a GUID or similar high-entropy token. The token could be a parameter in the query string or part of the URL path itself.  It doesn't really matter.
  4. Allow only one valid token per user at any given time.
  5. Make sure the email message does not include the username.
  6. Make sure the link can be used only once.  In other words, invalidate the token immediately when an HTTP request containing that token is received.
  7. The link should expire.  Depending on your situation, implement logic to invalidate the token 10, 20, or 30 minutes after the email is sent out.  Make it a configurable value so it can be adjusted if needed without a code change.
  8. The password reset page (the one that appears after clicking the link) should force the user to re-enter his username.
  9. If the username entered is incorrect 3 times in a row, lock the account.  Remember, your application knows which username is associated with the token.  The person attempting to reset the password should know it as well.
  10. After a successful password reset, send a confirmation email to the user to notify them it happened.  This can alert users to fraud if they didn't initiate it.
  11. Throughout each step of the process, make sure the application is logging everything that occurs so there's a solid audit trail in case something goes haywire.
So those are the mitigating controls I came up with.  Feel free to let me know in the comments if you have any other ideas!

(updated on May 5, 2014 based on some feedback I received)

3 comments:

Terry Bradley 5/05/2014 11:10 AM  

I think these are very good guidelines and they're giving me ideas for additional tests I should be doing on the web apps I test...

One additional point (and this may be overboard given your stipulation that the developer does not know much about the user) would be to include some "out of band" notification to the password hads been reset (regular mail, text message, etc.).

Alternately, I would recommend a "delayed" email notification to the user that the password has been reset. Obviously an attacker that has control of a victim's email could delete this notification, but he may not have the flexibility or patience to wait around for a delayed notification (especially if it's several hours or a day later).

Dave Ferguson 5/05/2014 4:18 PM  

Hi Terry - yes this write-up is for when you don't have an out of band channel. And I think a delay in sending the notification makes perfect sense in this situation. Thanks

AndrĂ©,  5/06/2014 7:27 AM  

If you only have email, you can also use an email roundtrip, obviously. But there is more than one option to include the roundtrip.
A parameter that is most often not taken into account is that web traffic is SSL protected, email is not protected.
If you forgot your password, enter a new one via https. The response email contains a confirmation token, nothing else (no uid, no password). Upon reception of the confirmation token, change the old in the new password.
Now you avoid many problems.

  © Blogger templates The Professional Template by Ourblogtemplates.com 2008

Back to TOP