Think your passwords are secure? Think again! (Part 3)

No matter how good a password is, it provides little to no security if it is not stored and managed properly. Unfortunately, many online services have heinously-poor security practices. But that does not mean yours has to.

This week wraps up the password series with a look at what to do and what to avoid when developing systems that have to store and manage user credentials. If you are a software engineer and missed Part 1 or Part 2, you may want to read them first, even though they are not programming-oriented, in order to set the tone for why this post is important.

Avoid implementing poor password handling practices

As we did with password handling for users last week, let’s start with what to avoid when writing code to store and manage passwords.

  • Do not store passwords in plain text. This one probably makes you think, “No, duh! Why would I store passwords as-is, with no protection at all?” However, a recent case of this was brought to light at Yahoo!. More specifically, a service that they acquired stored passwords in plain text and a SQL injection attack yielded the whole list. So, whether you are writing the code or inheriting it, this is still a valid issue to watch out for.
  • Do not store encrypted passwords. When storing customer passwords in a database, encrypting them is not good enough. If you or your code can access the original passwords, someone else can too. There is no need to ever reconstruct the original password. More about this later in this post.
  • Do not send passwords via email. Your customer just created an account and set their password. They do not need you to expose it via email, which is completely insecure. If they forgot their password and want to get it back from you, emailing it to them rather than providing a reset mechanism is a poor practice. It is likely that they use the same password on more than just your system.
  • Do not make your own algorithms to secure passwords. Very few people on our planet have the skills, experience and expertise to create cryptographically-secure algorithms and methods. Unless you are one of them, use well-known, peer-reviewed solutions. Being peer-reviewed is especially important as demonstrated by the history of the formerly-classified SkipJack encryption algorithm, which researchers found to have significant vulnerabilities the day it was declassified by the US government.
  • Do not restrict the length and type of characters for passwords. This is a classic warning sign that a system has poor password management. If, for example, your database’s password field is limited to 16 characters and you have to forbid the use of special characters such as # and ‘, you are unnecessarily crippling its security. Proper hashing eliminates these restrictions.
  • Do not use security questions. Security questions that are intended to authenticate users reduce the security of systems. Answers to these kinds of questions are easily guessed or discovered via social networks or social engineering.

Best practices for storing and managing passwords

The methods for properly handling passwords are well known, but often overlooked, ignored or thought to be too much work to implement. You owe it to your company and your customers to do this correctly.

  • Use a secure channel. When transmitting user names and passwords to/from your system use SSL/TLS to encrypt the data. This includes during login, changing passwords and resetting them. Ensure that the page on which the user enters their user name and password is clearly denoted as encrypted (e.g., the URL should be using HTTPS and identified as encrypted by the browser). I have seen many HTML forms submit a password via SSL, but the form itself appears on a non-encrypted page, which is misleading.
  • Use a genuine SSL certificate. Self-signed certificates are not acceptable for customer-facing services. They trigger scary error messages in Web browsers and provide no means for protecting against a man-in-the-middle attack on your communication channel.
  • Salt and hash passwords before storing them in a database. Hashing enables your system to accept passwords of any length and complexity, circumventing the need to filter them for characters with special meaning to databases. Defuse Cyber-Security has an excellent article describing, in detail, how to do this properly and includes example source code for PHP, Java, C# and Ruby. See Secure Salted Password Hashing – How to do it properly.
  • Provide a mechanism to reset passwords. Notice that I did not say that you should provide a mechanism to recover passwords. If you properly salt and hash passwords, they should not be recoverable by anyone. Gmail and Amazon are examples of this kind of reset method. When implementing this, I would caution against giving an error message if a user’s name or email address is not found during the reset request. Doing so provides information to an attacker about which accounts are valid. Also, do not disable the account when a reset is requested. This could cause a denial-of-service condition since someone besides the account owner could have initiated the reset.

Further reading for the security-conscious

This series is by no means intended as the last word when it comes to password security. It is important to be diligent about staying up to date on security best practices and new vulnerabilities, especially if you are a software developer. Below are a number of good resources and I welcome your recommendations for additional ones. Just post them in the comments.

4 thoughts on “Think your passwords are secure? Think again! (Part 3)

  1. Peter, this programmer’s guide seems very sound, but I can’t help point out that some of it runs counter to the conventional wisdom in user experience design, specifically the mandate to “reduce any friction” that users feel in accessing your product or service (including when people forget their passwords).

    For example, consider not having security questions. Users really appreciate these when trying to get back in, but I understand they weaken security because they are usually the same stock questions, and are guessable or discoverable.

    But I have noticed a few sites staking out a middle-ground on this, where they have come up with very off-the-wall security questions (and then force you to answer them). Like, “What was the first name of the first school bully that you encountered?” It seems these types of questions would be a lot harder for hackers to guess or discover on your social networks, but still would get the job done of validating identity.

    • Obscure questions can still be problematic because their answers are usually dictionary words or names, as in the example of the bully question. Then, there is the issue of uniqueness of the questions and answers across sites. Unless you can have different obscure questions for all the sites where you need security questions, a breach of your account information at one site enables the attacker to easily answer the security question for your account at another.

      Having a proper reset mechanism is sufficiently easy to use while being more secure than security questions. If you really must have security questions, then use them in conjunction with a secure reset mechanism rather than in lieu of one. Layering security is a good thing. Having the security questions as a second layer of defense can help thwart an attack where the perpetrator has, for example, already hijacked your email account.

  2. These were very nicely written and informative articles. We all need to be more proactive about our personal account security. I wish would have been mentioned Two-Factor Authentication more. I use 2FA across a lot of my accounts. I feel a lot more secure when I can telesign into my account. If you have that option available to you use it, it is worth the time and effort to have the confidence that your account won’t get hacked and your personal information isn’t up for grabs. It would be nice to see more of the leading companies in their respective verticals start giving their users the perfect balance between security and user experience. I know some will claim that 2FA makes things more complicated, but the slight inconvenience each time you log in is worth the confidence of knowing your info is secure. I’m hoping that more companies start to offer this awesome functionality. To me this should be a prerequisite to any system that wants to promote itself as being secure.

    • @Justin: I agree that adding two-factor authentication is a good thing to do. I included some links to Google Authenticator, for those who want to add 2FA to their systems, and a WordPress plugin that utilizes it if you have your own WordPress blog. A post about using one-time passwords is a good idea. I’ll add that to my queue. Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>