Today I ran across an awesome blog post from earlier this year on web database security: "Everything you ever wanted to know about building a secure password reset feature."
Since reading online tales of some of the horrible things that crackers have been able to do to get to people's account information, I thought that this was a fascinating set of guidelines on building a database of users and passwords the right way.
The original article is worth a read, especially if you are working on any database of users, but it's a long read. Here is my brief summary for your convenience (and perhaps someday for my future reference):
- In your database, store passwords as a one-way hash with a salt that is also stored in the table.
- Don't send the user's password to them. (Doing the above will obviate that.)
- If user requests a password reset, send an email regardless of whether that email is associated with an account. (If it's not an account email, you can tell them that in the email, NOT on the web page.)
- In the password reset mail, send a time-limited URL with a unique code that allows them to go in and set a new password; do NOT send a new password. (See point 2).
- Consider using a CAPTCHA on a password reset form if automated attacks are an issue.
- To avoid problems where somebody's email is compromised, a password reset might contain secret questions. If you do this, make sure that they are concise, specific, diverse, hard to discover, and constant over time.
- Secret answers should be stored encrypted in the database. (Hashes are problematic if they need to be verified by a person.)
- Consider two-factor authentication.
- Do not allow password reset via username, only email address
- In your password reset emails, indicate the IP address of where the reset request came from.
- Notify the account owner via email when account information is changed.
- Do lots of logging (but without sensitive information) to help uncover malicious behavior.
- Do not lock out the old password from working until the new password information is completely verified.
All in all, a good overview. Hopefully more and more account providers follow this kind of advice — I cringe when I see my password sent to me over email in clear text!