10 Rules to Protect User Passwords
01 May 2009 | By Ian in Development, Misc, Opinion, PHP, Rants, Security
Most programmers take a pragmatic approach to security and scale their efforts based on an estimate of the sensitivity of the data they are storing.
The unfortunate truth is that password security is frequently underestimated, making it easy for credentials to be sniffed or stolen. Users often keep a very small collection of passwords, with many people memorizing a small collection and using them on almost every site and service they use. A password compromise on one site can lead to a compromise on many.
#1 Only store salted password hashes, not the plaintext password itself
The cardinal rule for handling user passwords is to never store the password itself. You should only store a hash (one-way encrypted representation) of the password, cryptographically salted with a string at least 16 characters long. When you want to check a user’s login, simply re-hash their input with the same salt and compare it to the hash stored in your credentials table.
#2 Never display a user’s password
There is never a good reason to display a user’s password on a web page. If they have forgotten their password, send the user through a password reset procedure. This also includes displaying their password in HTML forms. Don’t send the user’s password out as the value of a password form field input. This is almost as bad as displaying it on the page.
#3 Use the password field in forms
On occasion, a site will not use the “password” input field type on a login form. Any sensitive input acting like a password should be presented as a password input. This provides basic protections against caching, copying, and prying eyes. This applies to passwords, PINs, SSNs, and other private authentication data.
#4 SSL encrypt pages where users create new passwords
Prevent packet sniffing password theft by encrypting pages where the users are changing or creating new passwords.
#5 Protect passwords sent over non-encrypted connections
If you can, SSL encrypt any page where a user is sending their password for login. In places where this may not be an option, consider using javascript to prevent the password from being sent in plaintext. (More info on this in a later blog post)
#6 Never store passwords in cookies
Many developers don’t consider the fact that cookies are sent by the user’s browser for every request to a domain, including requests for images, CSS, and javascript. All this traffic makes it extremely easy to sniff passwords stored in cookies. Passwords stored in cookies are also easily found by someone who has access to a computer’s harddrive.
#7 Enforce reasonable password rules
All sites need some basic rules around passwords to keep users from using poor passwords. However, don’t think you’re doing yourself or your users any favors if you implement rules like setting a maximum password length, requiring users to change their passwords too often, or preventing users from ever re-using a password once they’ve changed it.
Forcing users into situations like these frequently leads to password post-it notes stuck to monitors or the underside of keyboards. Sometimes, it even drives site users away (I’m talking about you, sharebuilder.com).
#8 Send confirmation emails when their password is changed
Whenever a user’s password changes, send a confirmation message to their verified email address. Tangentially, any email address change should trigger confirmation emails to both their new and old addresses. This behavior helps your users quickly find out when they’ve been compromised, which can limit the damage done by a malicious user.
#9 Never email a user’s password
Many sites feel they are doing their customers a courtesy by emailing them their own password when they change it or sign up. However, if your email account is ever compromised, a simple search for ‘password’ can reveal a treasure trove of passwords, allowing a malicious person to gain access to many more sites and services used by a user. The resultant password list may also be used against any other site that hasn’t emailed a user their password, such as their bank, PayPal, or social networking sites.
#10 Use a proper password reset system
When a user forgets their password, generate a random temporary password and email it to their verified email address. This should not overwrite their old password. Instead, it should be set to expire within a reasonable amount of time (a few hours) and if it expires, the old password should remain in place. If the user logs in with the temporary password, they should be required to enter a new password before continuing to the site. The temporary password should then be expired and unusable on that account.
02 May 2009 | ait yahia Said:
hello,
it’s a good ten commandment , i want to translate this in french and for this i need your grant if your are the owner of ticket
regards
02 May 2009 | Ian Said:
@ait
Please feel free to translate this post into French!
04 May 2009 | Links to Relevant Password and Security Posts « Supply Chain Technology Said:
[...] isnoop has posted 10 rules to protect user passwords here: http://blog.isnoop.net/2009/05/01/10-rules-to-protect-user-passwords/ [...]
06 May 2009 | Rob Said:
Great post, thanks :-)
22 June 2009 | bmac Said:
I can’t believe how often #9 gets broken. I find it infuriating.