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.