I'm thinking what are the best method to implement the forgot password. I come out with 2 ideas. One, when user click on forgot password, the user is required to key in the username, email and maybe date of birth or last name. Then a mail with temporary password will be sent to user email account. The user use the temporary password to login and reset the password. Another similarly but the email with a link to let the user reset password. Or anyone can suggest me a best and secure way to implement. I also thinking like if sending the temporary password or link, forced the user to reset the password within 24 hour or else the temporary password or link will not be usable. how to do that?
If you include an email address with the registration. The "forget password" button sends an email to that email address. It ensures that the information is send to a trusted email.
(Unless the database is hacked, but then nothing is safe).
I'd go with the second approach. In fact, I have. It's like this:
- The user enters his username and hits "forgot password". Optionally you can ask for email and look the username up by the email, but this might fail if two users share the same email address.
- The system has a table
password_change_requests
with the columnsID
,Time
andUserID
. TheID
is a long random ID (GUID might do). TheTime
column contains the time when the user pressed the "Forgot Password" button. When the new user presses the button, a record is created in the table. - The system sends an email to the user which contains a link in it. The link also contains the
ID
in the above mentioned table. The link will be something like this:http://www.mysite.com/forgotpassword.jsp?ID=01234567890ABCDEF
. The forgotpassword.jsp page should be able to retrieve the ID parameter. Sorry, I don't know Java, so I can't be more specific. - When the user clicks the link in the email, he is moved to your page. The page retrieves the
ID
from the URL and checks against the table. If such a record is there and is no more than, say, 24 hours old, the password is changed to a new random password. The record is also deleted, so that it cannot be reused. - Now you have a choice of how you want to display the password to the user. You can either send another email with it, or display it on the screen. Or both, just to be sure. I always like to send important information to the email as well, because that makes it easier for the user not to forget it.
Just ask for the e-mail address and if that's associated with any user reset the password and send it to the address (you shouldn't be capable to send the original password as it is hashed... it is right?). The temporal password might have an expiration period or could be cancelled if the user enters the right one in the log in form.
With this method the steps needed to reset a password are minimal. The simplest the better
It all depends on your site and the level of security that you're trying to achieve but the basic process for a web app goes something like the following:
The user navigates to the 'forgot my password' page and enters their username or email (whichever is unique) to request a password reset.
Optionally at this stage you can confirm the request by asking for additional information such as the answer to a predefined security question or their date of birth etc. This extra level stops users receiving emails they didn't request.
Look up the user's account. Save a temporary password (usually a GUID) and timestamp against the account record. Send an email to the user containing the temporary password.
The user either clicks on the link containing the temporary password and the user's identifier in the email or navigates to the 'forgot my password' page and copy & pastes the temporary password and their identifier. The user enters their new password and confirms it.
Look up the user's record and if the current time is within a specified time limit (e.g. 1 hour) of the timestamp saved in step 2 then hash and save the new password. (Obviously only if the temporary passwords match!). Delete the temporary GUID and timestamp.
The principal here is that the user is emailed a temporary password that let's them change their password. The originally stored password (it should be hashed!) is never changed to a temporary password in case the user remembers it.
The original password will never be displayed to the user as it should be hashed and unknown.
Note this process relies entirely on the security of the user's email account. So it depends on the level of security your wish to achieve. This is usually enough for most sites/apps.
As said, it depends on the level of security required, however, if you need a higher level, some novel solutions I have seen include;
Displaying half of the temporary password when the user's identity has been confirmed (security question, email address etc.) then the other half being sent to the email account. If the email account has been compromised, it is unlikely that the same person has also managed to perform a man-in-the middle attack. (Seen on UK Goverment Gateway)
Confirming identity via email and another medium - for example a code sent via text to a registered mobile. (Seen on eBay / PayPal)
For somewhere in between these two extremes implementing security questions may be the way to go as mentioned by DaveG.
When you are sending any information via email, it won't be secure. There are too many ways someone can get it. It would be child's play for a skilled hacker looking to steal your information.
Refrain from sending any personal information like passwords and income information via email as it can become VERY EMBARRASSING for you and your organization if such information was leaked or stolen. Think about security seriously. It just takes that one incident for all the bricks to fall.
As for password retrieval, thoroughly read Forgot Password Best Practices.
The bottom line is that an application following best practices should allow a user to reset his own password. Personal security questions should be used. The application should not send email, display passwords, nor set any temporary passwords.
I would enforce unique email addresses across the accounts.
Then it is a simple matter of sending a link to a temporary page that allows the person to change their password. (allow 24 hours or less)
The user's email account is the weakest link in this scenario.
Never email a password to the user. Even if it is auto-generated. Best approach (recommend and used by SANS and others):
- On the forgot password page, ask the email/user id and a NEW password from the user.
- Email a link to the stored email for that account with an activation link.
- When the user clicks on that link, enable the new password.
If he doesn't click the link within 24 hours or so, disable the link (so that it does not change the password anymore).
Never change the password without the user consent. It means do not email a new password just because someone clicked on the forgot password link and figured out the account name.
I'll go with:
- Ask user for email, check email is registered
- Generate GUID, and send it to that email
- Do not reset password yet
- User clicks link, and then have to enter new pass
- Reset password only after user is in your site, and have clicked reset button after typing new pass.
- Make that GUID expirable within a short time period to make it safer.