We’re not using Windows 95 anymore. Few Pentium I systems remain in production use, and the majority of the world no longer connects to the Internet through telephone lines and analog modems (though some poor souls still do).
If those days are over, then why do the horrible software design and security practices that stem from that era still roam the Internet -- and in new code?
I suppose some forgiveness should be granted to very small companies that lack the resources to build or even conceptualize a highly secure system. However, there’s no excuse for companies in financial, health care, or other large industries to get it wrong. At the very least, they should avail themselves of the vast array of best practice guidelines and freely available, thoroughly vetted code -- or hire someone who can. There's no need to reinvent the wheel (poorly) and expose yourself and your customers to fraud.
Commandment No. 1: Do not ever store passwords in plaintext
Who told you this was OK?
I’m demoralized merely typing that out. It’s 2015. We do not and should not ever store a password in plaintext anywhere. At the very least, hash with a salt, store it, and compare when needed. It requires very little work, and it's orders of magnitude more secure than storing a plaintext password. If you don’t want to write it yourself, there are libraries for every active language and several dead ones that will help. Please, for the love of Pete, stop doing this.
The fact is, we generally don’t know who is and is not securely storing login information. All we know is that we create an account with a password and basically trust the developer on the other side.
Commandment No. 2: Allow special characters
I shake my head sadly when I’m presented with a banking website that prompts me to change my password and I'm told it can contain only letters, numbers, and an underscore or some such nonsense. A password should be able to contain any printable character within the supported character sets. There should never be a design or compatibility reason to deny special characters in a password.
I had one fellow remark that his database couldn’t properly store special characters in a password, so the company limited it to alphanumerics. There was so much wrong with that statement I didn’t quite know where to begin. Instead, I advised him to start over from scratch and possibly set the entire dev platform on fire to make sure it was completely dead.
Commandment No. 3: Don’t modify the password -- at all
As we found out with the Ashley Madison scandal, some sites upper- or lowercase passwords on the way in or they strip characters. Thus, if your password is sd!!HF345FFJj@s, it’s stored as SD!!HF345FFJJ@S in the database, hashed or not. Or worse, it’s stored as SDHF345FFJJS because the code strips out all the special characters. This happens in a surprisingly high number of cases, and it boggles my mind every time I see it.
Commandment No. 4: Do not ever, ever, ever email a user their password in plaintext
I cannot believe this still happens. The reason I’m writing once again on good password and data hygiene is that I recently purchased a part from an online company with a solid rating from Google and others. I had to create an account to place the order, and I used a credit card to complete the purchase, much like millions of people do every day. The order went through and all was well.
Moments later, I got an email welcoming me to the store and advising me that I was a highly valued customer, which was nice. The company included a few sentences about how I should click the following link to log back in and to use the following username and password. The password I had entered was right there in plaintext ... in the automated email -- sent without any encryption.
To recap: This place has my name, address, personal email, phone number, and credit card info; presumably stores it all in plaintext; and sends that data around unencrypted. One can only imagine the quality of the code running the rest of the operation. I wish this was exceptionally uncommon, but it’s not.
Never send a user their own password. Read the first rule again and remind yourself that you should never know their password at all. If you have to reset a password, then do it via security questions and allow a Web reset via SSL, or send a link via email that requires immediate password change, and authenticates based on a random key in the URL. Alternately, use the libraries and methods that already exist for doing this securely. This is supersimple stuff.
Even worse, this affects more than the site in question. Many people use the same password for the majority of the accounts they create online (obviously not advisable, but very common). When a hacker breaks into a site that stores passwords or other data in plaintext -- which probably won't be hard -- all the hapless users whose data is exposed will likely find that their accounts on other, perfectly secure sites have been compromised as well.
I sincerely hope the day comes when revisiting these basic concepts becomes unnecessary. It will be a good day. Unfortunately, it’s probably much further away than any of us imagine.