Programmer Justin James presents five common ways to reset passwords for online applications and explains which two of the options provide the most security.
I recently had a discussion with someone about what goes into a good self-service password reset system for online applications. It seems like such a trivial thing, but it brought up a number of important security issues, which related to how we write our applications. I am going to lay out some common password reset approaches, what kinds of scenarios they work best in, and when to use one over the other.
Option 1: Email the original password
A good number of applications email the original password out. This is absolutely horrifying. It means the programmer has the password available either in plain text or a two-way encoding that can easily be turned into plain text. Forget for a moment the security implications of sending a password via unencrypted email; what happens when an attacker gets a hold of that database, or manages to get it to start coughing up that data? Everyone who uses that password on other popular sites is at risk. Not only should you never do this, your system should not be capable of doing it.
Option 2: Email a new, random password
This is not the worst choice in the world, especially for a site that doesn't have much sensitive data. You can just send out a new, randomly generated password, and suggest (or force the user) to change it when they log in again. The security is provided by their email system. This is a potential security hole itself, but for a low-value system without the kind of data hackers would be interested in, this can work just fine.
Option 3: Email a limited time password reset link
Another path that uses email as the identity validation system is to send out a link that contains a long string of random characters that leads to a one-use, limited time password reset screen. This is more secure than option #2 because the link can only be used once and with a limited window that it can be exploited if the link got into the wrong hands. It still has the weakness of using the user's email system as the determinant of identity, though.
Option 4: Secret questions
More and more sites seem to be moving to the secret question scheme, where when the user signs up, they are asked questions that only they should be able to answer, like their mother's maiden name or their high school mascot. In my opinion, this is an incredibly insecure system.
First and foremost, anyone who knows me well (or is friends with me on Facebook) already knows or can find out my mother's maiden name, what high school I attended (and therefore, its mascot), my birthday, the first car I ever owned, my favorite pet, and more. To make matters worse, secret questions are often stored in clear text, which means that if a hacker gets the database for one site, they can answer secret questions at many sites. And unlike passwords, it is very unlikely that I am going to use different answers to the same questions on different sites.
The only time secret questions are truly secure is when they rely upon a site-specific piece of information, perhaps something that was provided non-electronically (like an account number that only appears in paper mail from the company).
Option 5: Reset via phone
Some sites are now sending a confirmation code through SMS messages to perform password resets. I like this strategy a lot. "Hacking" my SMS address involves actually getting a hold of my phone (or planting a virus on it, and some phone operating systems, like Windows Phone 7, won't allow apps to read SMS anyways), which is an entirely different level of security breech.
The big downside is for users without access to SMS messaging; depending on your target audience (such as military personnel in highly secured locations, people in remote areas, etc.) this may well be the case. It also presumes that you have a way of sending SMS messages, which is not the easiest task in the world and usually involves signing up for a third party, paid service.
Which option to choose?
In my opinion, options #3 and #5 provide the most security. Option #3 does not send any passwords through the email, and if the email system is hacked, compromised, or otherwise exposed, the attacker has only a limited time to do something with it. For example, if your emails end up as court evidence, no one can take action on the one-use, limited-time link (thanks to Chad Perrin for reminding me of this). Option #5 has the advantage of requiring physical possession of the authentication device. In addition, it avoids email completely. Out of the other three, option #4 is probably the worst, because it requires you to store sensitive data that is not relevant to the application, data that is dangerous in the hands of an attacker, and the authentication is based upon easily obtained information.