This afternoon I signed up to a new web-based application from a very well-known media company. I gave them my email address and the password that I wanted to use and a few minutes later I got an email from them confirming my registration.
That was fine. But then I noticed that the email from them contained the name of their site, my username and my password. All in plain text. This is a breach of basic internet security processes. And thinking about it, I’ve seem several similar breaches recently. So I thought it was worthwhile making a note of some of the rules you should be following when handling users’ passwords on web sites and in emails. A sort of “Password Handling 101″.
Rule 1: Don’t Store Plaintext Passwords
This is the fundemental principle that all the other rules follow from. It is non-negotiable. If I give you a password to use on your web site then I should be the only person who knows it. I don’t want it stored unencrypted in your database so that any of your staff can look it up.
“But,” you say, “if it’s encrypted, how can we check it against the password you give us when you log in?”
“Easy,” I reply, “you do it the same way that Unix passwords have been checked for decades.”
You store the password using some encryption algorithm. The stronger the better. Then when I give you a password for you to check, you encrypt the new password using the same algorithm and compare it against the encrypted version in your database. If the two encrypted strings match then I’ve given you the correct password and you can log me in. Simple isn’t it?
“But,” you say, “if it’s encrypted, how can we tell you what it is if you forget it?”
“Simple,” I reply, “you don’t.”
If I forget my password then you have two options. Option one is that you generate me a new password, email it to my registered email address (but see rule 2 below) and store an encrypted version of the new password in your database. Option two is that you send (to my registered email address) a link to a web page where I can enter a new password. This link should obviously be time-limited (so I can only use it for a few hours) and should contain some encrypted key so that no-one can guess what the link is. The second option is less secure as anyone can intercept the email and get access to the link, so the first option should be prefered.
Rule 2: Username and Password Travel Separately
The problem with internet email is that (unless you use something like GPG) everything is in plain text and anyone can intercept it and read it. It’s like you are sending every letter on a postcard rather than in an envelope. For this reason you should never put the username and the password in the same email. The forgotten password scenario above should be the only reason why you ever send a password to a user in an email. So don’t put the username in that email as well.
Rule 3: Web Pages with Passwords Should Use HTTPS
Like email, by default, all web traffic is unencrypted. Anyone can potentially read anything that you send to a web site. So when I log on to your site and I enter my username and password, anyone can potentially intercept those values and that will enable them to log on to your site as me. If you serve login pages using HTTPS instead of just HTTP then that login transaction will be encrypted all the time the data is on the public internet and it will be much harder for anyone to extract my login details.
Three simple rules that every web site should be following. And it’s surprising (or, at least, it surprises me) how many sites don’t follow these basic rules. Following these rules won’t make your site impervious to people determined to break into in, but it will go a long way to making your users’ accounts more secure.
I was going to name and shame the site that I dealt with this afternoon, but I wrote them a polite email explaining the problems and in less than 45 minutes I got a reply saying that these problems had already been noted and that they should be fixed by the end of the week. That’s pretty good customer service so I won’t embarass them by telling everyone who they are.