“Website Passwords Hacked” headlines can be less scary
Have you ever read that title? A website’s password database has been stolen? It just happened again today with the popular Cupid Media websites. In this case, over 42 million passwords affected! The worse part of this, and completely unacceptable fact is that the passwords were being stored in plain text. I’ll explain here why that is such an issue.
I’m an entrepreneur, and just hired someone to build a website for me that has a specific purpose. Users sign up to the website by creating a username and password, something we’re all familiar with these days if we’re regular web users. I only assumed that the passwords would be stored so they were cryptographically hashed, but I was incorrect. I decided to connect to the database, and take a look at the users table.
Archived image unavailable: password screenshot.
As you can see in the above screenshot, the first 3 columns are id, username and password. In the case of the first two accounts, the password was “password”.
What’s wrong with this picture? Even as the website owner, I should not be able to read the passwords in plain text, they should be using a cryptographic hash function.
This is why you should not use the same password on more than one website. Whoever has access to the Cupid Media password list above, can try your email address and password now on other popular websites like Facebook, Gmail, or your bank. If you use the same password, they now have full access to your account on those websites as well.
Here’s a quick example on the shell, if I use perl to print the plaintext password, “password”:
$ perl -e "print qw(password)"
password
Now if I do the same thing, but run it through SHA sum:
$ perl -e "print qw(password)" | shasum
5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8 -
SHA sum also takes arguments, say for example I wanted to use the more popular SHA-256 instead of SHA-1:
$ perl -e "print qw(password)" | shasum -a 256
5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8 -
Note if I change only one character in the password (passvord instead of password), the hash changes significantly:
$ perl -e "print qw(passvord)" | shasum -a 256
4178bba48157987d64960917284f7b9e53d09eb88fca1d8dcbd934935f0a6216 -
and yet if I make the password significantly longer, the hashlength doesn’t necessarily change:
$ perl -e "print qw(STRONGpasswordsareAWESOME)" | shasum -a 256
0fc67f38c340a769633d22a953c0773ec032205156f2519833a72807c4e40a6d -
As you can imagine, it’s going to take me a lot longer to know your password is “password”, even if I own the website, if what I see in the database is “password” vs “5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8” in which case I would need to crack the password.
There are two factors in determining how hard it is for me to crack a list of hashed website passwords. The first is still how simple the passwords are. Typically this is done using brute force on a list of dictionary words. These lists usually start with “123456” and “password” and after normal English words expand to words like “p4assw0rd”. What the cracking program will do is hash each of these words using your hashing algorithm and compare to see if the hashed strings are identical. If they are, I now know the password. This is why it’s important to use long passphrases.
“Ilovebutterfliesandeatingpicklesinautumn” is going to be very very far down a dictionary list [1], even though it only contains letters. Add numbers and special characters like $ or # to make passwords even more hard to crack.
The final thing for database administrators to think about is which hashing algorithm to use. The two most common methods, md5 and sha-1 are both susceptible to collisions, or birthday attacks. As of writing this, I would recommend using SHA-3-256 which has no known attacks.
On top of just hashing the password, you can add a salt, a new randomly generated string, which is concatenated with the password before hashing each password. This makes is exponentially more difficult to crack through password lists, as well as removes the potential of using rainbow tables for cracking. Many hashing libraries will allow you to salt each password differently, instead of a global salt for every password. In the next example I’ll take the password of password and add the word salt as a salt, and run it through crypt using $6$ which says you want to use SHA-512:
$ perl -e 'print crypt("password","\$6\$lesalt\$") . "\n"'
$6FMi11BJFsAc
Additionally, if you are a website owner that wants to be proactive, what plans do you have in place to be notified when your hash algorithm has been compromised? And when you are notified, what is the process of upgrading your database?
In this example, this bizarre combination of words is so far down a dictionary list, it would take roughly 3 sexdecillion years to crack using a normal PC! You can test out the strength of passwords using https://howsecureismypassword.net/ but of course don’t use your real passwords, or now they will know them.
Need this translated for your organization? PrivaSecTech offers confidential briefings, policy reviews, workshops, and privacy/security advisory for teams that need to decide what to do next.