I take password security very seriously. I’ve already written about how people can improve their password habits to keep themselves safe. This piece, however, is for those of you who build websites which provide password-related functionality.
This is a list of password crimes that some websites commit. I’ve described these crimes, then point out some criminals (a.k.a., websites) which commit these crimes.
(This list is not guaranteed to continue to be up-to-date. This post represents a snapshot in time, and is accurate as of early June 2014 when the first draft of this post was written.)
Basic usability
-
I should always be able to change my password from within my user preferences. If I have to log out and pretend like I’ve forgotten my password in order to change it, your system is broken. (Authy, TunnelBear)
-
If anything with your site or service requires a password, always allow me to change it from the web — even if changing my password is the only thing I can do. (Automatic, Zite, Steam)
-
Make it super-easy to find where to change my password. Do not bury the link to make it more difficult. (LinkedIn)
-
If my password change was successful, please tell me very clearly. If not, please tell me very clearly. (Last.fm, Disqus, Bible.com)
Provide clarity at all times
-
If you require my current password in order to change my password, then ask for it up-front. Don’t hide it, then surprise me. Don’t ask for it after I’ve put in my new password. Be direct and forthcoming about it. (Kickstarter, CloudApp, Spotify)
-
Be explicitly clear about what the password requirements are. Not just the low-end — make sure you document the high-end requirements too. I often run into cases where my passwords are too secure for the system. (Morgan Stanley, Life 360, H&R Block, Zendesk, Beatport, Secure Checkout by Visa)
-
If you wait until after I try to change my password to tell me how long it’s allowed to be, you’re a huge jerk. (H&R Block, MyFitnessPal, SourceForge, Secure Checkout by Visa)
-
If my password is too long, don’t complain that it’s too short and not tell me the maximum allowable length. (Beats Music)
-
If you list your password requirements on your website for people to use, make sure that the ones you list are actually correct. (Morgan Stanley, Secure Checkout by Visa)
Avoid confusion
-
If I’ve managed to inadvertently create two accounts, make it easy for me to merge them. If you suck, and require me to delete one of them, then actually delete the account. (Adobe, Readability, Facebook)
-
Never allow two accounts to have the same email address, then allow users to login with their email address. There is a 100% chance that this will ruin someone’s day. (Readability, Amazon Web Services)
Provide a useful “forgot password” page
-
On the “forgot password” page, always allow me to enter my email address. I may not always know some random username, but I will always know my email address. If I try to look-up my password and you ask for a username (i.e., lookup by email address is not supported), then make me go to another lookup for my username, your system is broken. Support both if possible, otherwise err on the side of email address. (Pottermore)
-
If your password change/reset form(s) accepts my new password, then the login page should too. If my password doesn’t pass validation for logging in, then it shouldn’t pass when I change it via account preferences or the “forgot password” page. (Morgan Stanley)
Be liberal in what you accept
-
Never tell me that an email address with the “+” character is invalid. Yes it is. You’re dumb, you’re ugly, and your mother never loved you.
-
You shouldn’t be storing my real password, ever. You should only be storing a cryptographic hash of my password for comparison. (Never use MD5 and never use SHA–1. You should be using SHA–256 at minimum, which is 64 hexadecimal digits long.) Because of this, the following principles should always be true.
-
Accept any password I give you, and be happy about it. Even if it’s 128 consecutive
NULL
bytes, or a long string of multi-byte characters, accept it gladly. Chances are, I’m smarter than your system, so allow me to be. (Anyone who limits supported characters.) -
If you accept only certain “special characters” (a.k.a., “characters” — none are “special”), be explicitly clear which ones they are. If I try to use “£” in my password, but it isn’t allowed, tell me: “Your password contains the ‘£’ character, which is not allowed.” (Usability bonus)
-
If you have a length limit on passwords, the string limit should be no smaller than 64 bytes. Yes, 64 bytes. The next bank (or other service) to tell me that my password may only be 5–12 alphanumeric characters is going to immediately lose my business. (Life 360)
-
Support OAuth consistently, or not at all
-
If you allow me to sign-up/log-in to the desktop version of the website with Facebook (or any other OAuth provider), then you must always have that login option available everywhere else (e.g., mobile web, native mobile app, being an OAuth provider, asking for my password to change my password). I don’t have a password otherwise.
Real security, not “Security Theater”
-
Instead of asking me random/stupid “security questions”, give me the option of using two-factor authentication. It’s more secure and easier to use. (Pretty much every bank and financial institution on the planet.)
Don’t break the web
-
Never prevent me from copy-pasting my password. I use a password manager so that I don’t have to remember it, you pretentious prick. (Paypal)
-
Understand that an increasing number of people are using password managers. This is a very good thing. This also means (a) the username and password fields should always maintain the same HTML field name, (b) if you change the URL, the old URL should redirect to the new one — especially if you’ve changed the login domain. Otherwise, you end up breaking your customers’ experiences. (Amazon Web Services)