Linked In this week coughed to having a load of passwords stolen from the site (somehow) and it has once again opened the "how safe is my password" can of worms. There are some givens in the world of passwords, one seems to be that people use the same password for lots of sites and the other is that you have to play a game between requiring your passwords to be 'uncrackable' and making it annoying for people to have to use some strange password.
What did Linked In get wrong? The fact that their passwords were hacked is unfortunate but it isn't something you can easily protect against. Data can be lifted in so many ways, even with trusted suppliers (look at Brighton and Sussex NHS having their old hard disks flogged on ebay by the contractor who should have been destroying them!). The question is, therefore, if somebody did lift the passwords, how sure can you be that they cannot be decrypted. It would appear Linked In, despite their size, had a miserably poor mechansim. Here, therefore are some rules to keeping passwords in a database for a site:

  1. If you can use Single Sign-on, use it. Let security be the problem for large well-funded companies like Google and Facebook!
  2. Never, ever, ever, ever store a password in Plain Text. If someone forgets their password, allow them to reset it, you do not need to tell them what it was.
  3. The standard way to store passwords is to hash them using a hashing algorithm. Use a commercially accepted and secure algorithm and keep updating it where possible so that older weaker algorithms are removed and replaced. Linked In used SHA1, something not known (nowadays) for its good security.
  4. Always, always, always salt the passwords before hashing. You need to understand how hashing works to understand this point. Hashing will always turn a given password into the same value hash. When a user enters their password again, it is hashed and compared with the previous hashed value to see whether they match. Hash algorithms are considered effective because it is considered mathematically un-feasible to reverse the hashing process and turn a hash into the actual password. This might seem wonderful but hashed passwords can be attacked another way when using industry standard (i.e. known) hashing algorithms. Suppose your password is chocolate and when hashed it becomes 123456789, even though I cannot turn 123456789 into the word chocolate, what I can do is to run loads of words from a dictionary through the same hashing algorithms and store them in some sort of database or lookup table. When I then look for 123456789, I can then see that it equates to chocolate. Salt is simply a way of changing the password before you hash it so that its hash value is altered into a form that is not a dictionary word. Imagine, for example, we add the string !"£$% to all passwords before hashing, chocolate!"£$% then doesn't become 123456789 anymore, it becomes something completely different, let's say abcdefghi instead. The point here, is that I will (probably) not find any dictionary words that will hash to abcdefghi but even if I did (imagine by some remote chance the word helicopter did) then if I tried to login with the word helicopter, the system would again add the salt onto the end and helicopter!"£$% would NOT any longer produce abcdefghi and the system would not log in. If you can keep the salt random and unpredictable (and secret!) then the system is basically uncrackable. Linked In did not use salt - a schoolboy error.
  5. These dictionary type attacks are the reason that some sites suggest passwords with numbers, mixed case and punctuation symbols in them, it just massively increases the amount of time it would take for a random password generator to get to the specific combination and has it. These password generator tools are not industry standard so we don't know in what order they operate so even using two words (e.g. chocolatepassword) is not necessarily that much more secure than one word. However, we can be fairly sure that Ch0colat3Pa$$w0rD would take a lot longer to come up in the password generator! For the same reason long passwords of several words would again take longer (if ever) to crack, especially if there is not much logic to the sentence. Consider the 'password', IWentForAGreenCoffeeByTheParkOnTheRiverWye
  6. Do not roll-your-own hashing algorithm unless you are a post-grad at MIT! you will not produce anything as secure as industry standard (e.g. SHA256, Whirlpool, RIPEMD) type algorithms.
  7. Keep user logins/email addresses in separate tables from password hashes. A hacker trying to retrieve two tables of data has a much harder job than trying to hack the contents of one table. A list of passwords without users is only of limited value (but it does give hackers some more passwords to add to their dictionaries)
  8. Setup security so that password hashes can never be retrieved once they are in the table (deny select). Use a stored proc to pass in the password to check.
  9. Have a quick and foolproof way to reset all passwords if a leak is confirmed (or suspected depending on how important your site is).
  10. Don't be coy, if you even suspect a leak, tell people immediately that you are investigating it so that the more paranoid people can take action straight away.
  11. It should not be possible for any website user to have privileges to access private database tables. Restrict site admins to general admin tasks and anything more deep should be done from another site on a private IP or directly on the database.
  12. Give your database tables obscure names which makes it harder for hackers. Do not use names like user, users, passwords, pwds etc.
  13. Hackers might use passwords gained from elsewhere to try and hack your site (or your user accounts). Ensure you have intrusion detection so that you can log and/or block failed logins. Someone should not be able to keep trying to login to an account until it works!