Search code examples
securityauthenticationmembershipforgot-password

How to keep passwords safe when a "Forgot Password" function is available


A colleague and I are discussing how to implement "Lost Password" feature on our company's proprietary web application.

We have already decided that to create an account there will be three required elements

1) Screen Name
2) Email Address (used for logging in)
1) Password (obviously, also used for logging in. Stored as one-way hash)

Once we have that info, the user attempting to sign up will be sent a verification email with a link and an activation key. To activate their account they will need to follow the link, enter the activation key, and re-enter their email and password. If everything matches then presto! A new user account is activated.

After the account is activated, lets say that the user forgets their password. We have two ideas for how to handle this situation.

Idea 1

  1. User clicks "Forgot Password"
  2. User is prompted for their account's email address
  3. If email matches active, non-closed account, then send a temporary password to the already validated email address
  4. User attempts to log in with temporary password
  5. If temporary password matches email address, prompt user to reset password. Prevent full login until temporary password is replaced.

Idea 2

This would require secret question and secret answer data to be collected during signup.

  1. User clicks "Forgot Password"
  2. User is prompted for email address and answer to secret question
  3. Upon validating both, user is then allowed to reset password

Concerns

One concern that we have is that (internal to our company) multiple employees would use a single login account. Some of us think that eliminates the secret question method as an option.

However, a password sent by email (temporary or not) would be vulnerable as email is not secure.

Question Summary

Considering internal operational constraints (multiple people to single login) which of these ideas would be the most secure and user-friendly option? Or, are neither adequate?


Edit

Could the stack overflow help me out by evaluating the answers? There are few opinions expressed below, but there isn't any indication from SO as to the answers' quality.


Solution

  • In my systems when someone requests a lost password I:

    1. I generate a GUID and store it in the database along with the date/time of the request.
    2. Send the user a link with the GUID encoded so that when they click on the link it ties them to that GUID
    3. Make sure that GUID/link has not already been 'used'.
    4. Make sure that the request is not older than 30 minutes (for security purposes they only have a small window of time to use the activate link - they known that from a message on the request password screen)

    If all those conditions are true, I let them create a new password.

    Generally speaking, though email is not terribly secure, if someones email account is compromised, you already have a huge security hole, but by telling them they only have 30 minutes to re-activate their accounts, it cuts down on the window when someone could misuse the information: it can only be used once, it goes to a known good email address, and it can only be used for 30 minutes...for the type of systems I have done, this is secure enough without burdening the users (or admins) too much.