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.
- User clicks "Forgot Password"
- User is prompted for their account's email address
- If email matches active, non-closed account, then send a temporary password to the already validated email address
- User attempts to log in with temporary password
- If temporary password matches email address, prompt user to reset password. Prevent full login until temporary password is replaced.
This would require secret question and secret answer data to be collected during signup.
- User clicks "Forgot Password"
- User is prompted for email address and answer to secret question
- Upon validating both, user is then allowed to reset password
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.
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?
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.
In my systems when someone requests a lost password I:
- I generate a GUID and store it in the database along with the date/time of the request.
- Send the user a link with the GUID encoded so that when they click on the link it ties them to that GUID
- Make sure that GUID/link has not already been 'used'.
- 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.
I've used the temporary password that is sent to the email, although it's not the most secure. You can also add a time limit to the temp password which would increase security slightly. I think multiple security questions and then sending a temp password to an email would be fairly secure.
As a user I dislike security questions, because in order to make them actually secure I have to make the answers very hard to remember.
Here's the pattern I would use:
- Forgot Password link sends user to a URL with a UID embedded in it
- The Forgot Password page sends an email that includes a code to be entered on that page
- The code is only valid when POSTed from a URL with the correct UID.
- If a valid code is POSTed from a valid URL, the user is sent to the Reset Password link.
The important thing to remember is that the mapping between UIDs and codes should not be predictable.
The rules for a company intranet access and login process may not be the same as those for a website or account accessed from the public internet. You could have email address and also part of the users employee/staff number and security pass or card serial number, or use a unique and confidential login id issued by IT support to each new user.