WebApp Sec mailing list archives

Re: "Forgot Password" function


From: Jeroen Latour <jlatour () calaquendi net>
Date: Fri, 18 Oct 2002 20:30:24 +0200

At 11:31 18-10-2002 -0600, Brecrost Jones wrote:
I'm looking for opinions on the most secure way to implement a "Forgot my password" function for a website. I know that having this feature is probably an inherent security risk, but __assuming that it is a required feature__ what would be the most secure way to implement it?

Is the "enter your email address and we'll mail you the password" the best way to go? As far as I can tell, it's the most common. But I'm not sure if I'm comfortable sending the password in a clear text email message.

I don't really like the "secret question" method either, since if someone can get the question, they may be able to guess the answer.

Are there other methods out there? Has anyone come up with a novel solution that is more secure?

I believe the best method is to allow the user to enter their email address (in which case the username is looked up) OR username (in which the email address is looked up) and send them an URL which they can visit within a day or so to change their password. This has the following advantages:

1) You can store the password using a one-way hash in the database, which is certainly a security improvement. If you store passwords in cleartext, people who break into your site and get a hold of your database can see the passwords that people have set. Now this may not be a big problem for you (they already broke in, so what does it matter?) but people are known to use the same password in a lot of places: a password on that list may well be the same password as they use to retrieve email.

2) By only changing the password after the mail has been received, you prevent a DoS-attack opening up by people using the 'forgot password' function to force a user to wait for a new password to arrive by email (special case: block an account when the email address is no longer valid).

3) You do not have to send the password in clear-text or for that matter any password. Changing the password will still be in clear text over a HTTP connection, unless you use SSL connections (https://).

If you're going to implement this, bear in mind that:

1) When someone requests a new password URL, create a cryptographically secure (read: impossible to predict) token which you can put in the URL (newpassword.ext?token or something like that) store along with a timestamp (and the username) in a database, waiting for the user to visit the URL. To create such a token, you can use a random number and optionally the username, email, current time, a secret key or any other type of (secret) information or a combination thereof, and run MD5 or another hash on it. Using MD5 ensures that you can't discover the original input from examining the hash, but if they can guess the original input they're still going to be able to produce the hash themselves. Use real random numbers.

2) Timestamp your hashes in the database, so that people don't have unlimited time to try and break the system. A day should be enough.

3) Optionally store who requests new passwords, so you can track them down if necessary. Also make a note in the mail that if the recipient did not request the new password, they should discard the mail.

4) You may still need to have a point of contact for people whose email address has changed and who can't access it anymore.

There are other options, usually using cryptographic techniques, but they usually require specialised software or hardware. For a general environment, I think this is the practice.

Of course by the time I typed this entire mail, others have replied with the same information. Bah. I hope it's still useful.

Good luck,

Jeroen Latour



Current thread: