Password Hashing Could Have Prevented 32 Million Headaches!

When it comes to security in web applications, just like with security in anything physical, you can never be totally and 100% sure that your data and application will be protected from malicious actions.   But there is a lot you can do to reduce the likelihood of a breach, and more importantly, there are some simple practices that can greatly reduce the damages and repercussions of a breach -- should one occur.

In regards to the RockYou service, which is a glorified MySpace page crapifier, 5 minutes of programming work and thought could have potentially prevented 32 million headaches (as well as a class action lawsuit) when a hacker exploited a security hole on one of their web pages. Why 32 million? That's the approximate number of users on the site who should now be changing their passwords to their e-mail accounts if they happened to share the same password with their RockYou account. 

Now I'm not going to criticize them for having the flaw, although it was a fairly fundamental SQL injection exploit that could have also been prevented. What I am going to criticize them for, as many others have done, is the storing of passwords in plain text.

While I don't know exactly how the RockYou code is structured, I can make an assumption about what they were doing for their login process:

When a user signs up, they enter their e-mail address and choose a password.  The RockYou site then inserts the obtained data into a database like this:

insert a user "martha@smith.com" with password "mysecret123" into database

Now when the user logs into the site, she enters her e-mail and password. RockYou looks in their database to find if the user exists and has provided the correct, matching password:

find a user "martha@smith.com" with password "mysecret123" from database

If it finds the combination it will allow the user to log in and everything is fine. The problem here is that everyone's password is stored in the database in plain text and when the breach occurs, the hacker will be able to access to everyones' passwords simply by exporting the data table -- which is exactly what happened to RockYou in early December. Compounding the problem is how most people use the same password on other accounts. Now the hacker potentially has access to thousands if not millions of e-mail accounts -- which in turn can be used in even more identity theft all over the place (think about how password reset forms work: they send you an e-mail to reset your password).

You could say that it is the user's responsibility to use a different password for every single website you log in to, but honestly, I believe this is just unfeasible. Most people are not going to remember 50 different passwords and associate them with 50 different websites without additional software. Of course, the use of OpenID on RockYou could have bypassed the whole mess without even needing passwords at all.

To fix this, all that has to be done is what's called password hashing (assuming you don't want to use OpenID as I mentioned). This is a mathematical process that converts a password into a bunch of seemingly random letters and numbers that makes it nearly impossible (think: 100 years) to obtain the original password. Here is the process applied to our previous example:

// create a hash of the user's password
sha1(mysecret123)
insert a user "martha@smith.com" with password "f2b14f68eb995facb3a1c35287b778d5bd785511" into database

Now when the user logs into the site, she enters her e-mail and password.

// create a hash of the password that the user entered
sha1(mysecret123)
find a user "martha@smith.com" with password "f2b14f68eb995facb3a1c35287b778d5bd785511" from database

Even if a security breach occurs, and the tables fall into malicious hands, all they will have is the user's e-mail address and associated "password hash" -- which is essentially useless information for gaining access to accounts.  Even the website's owners wouldn't know what their users' passwords are. This is why if you call some companies when you forget your password, they can't even tell you your password if you wanted them to, you have to reset it.

If you use hashing, please do not use MD5 as a function, since many flaws have been found in it. Use a stronger function like SHA1. You can read more about password hashing on Wikipedia's cryptography pages.

blog comments powered by Disqus

4 COMMENTS

posted by Alex Fierro on: Feb 1, 2010 01:48am

I was going to say "...and salt it", but looks like it was covered already. :-) If you don't wanna salt with a randomly generated salt string, you can salt with username or other unchangeable data like DB row ID. $hash = sha1($pass.$username); ...to prevent the hacker from checking the output hash from appearing in a decryption database... which is why even if it's hashed you should force user's to have a decent password! (AKA not "password")

posted by on: Jan 29, 2010 04:32pm

thanks, yeah would be pointless if the salt was not hashed as well lol

posted by Facebook User on: Jan 29, 2010 04:30pm

good point. I think you meant $password = sha1($pass . $salt) though to make the salt unreadable as well.

posted by on: Jan 29, 2010 04:14pm

Use salt as well, plain hashes aren't safe today anymore, there are Rainbow attacks and the likes of JTR if the given password is weak. An example of adding salt would be $salt="some_random_words_or gibberish preferrablylong with _ *^"; $password = sha1($pass).$salt /// retrieve the same way