Sony’s recent break-in is a big deal. Not just because their tables were snarfed, but because apparently they don’t hash passwords (and they store credit card numbers and expiration dates too, plus security questions and answers – but thats a gripe for another day). The password theft isn’t a catastrophe if your password is unique to Sony’s Play Station network, but it is if you’ve used that same password across the internet – on Facebook, Amazon, your bank, etc – and unfortunately many people still do this.

So, what if Sony had done it right and stored a salted hash instead of a recoverable password (either plain text or reversible encryption)? The bad guys would have names and email address, but that’s it.  No exposed passwords. Problem solved. Or is it?

Take the hypothetical world in which Sony was storing only salted hashes, but they were unaware of a persistent intruder (There have been several instances of this in the news lately, including RSA). Over SSL, an individual logs in or signs up. They type in their user name and password, and send it to the site. The site decrypts the SSL data, and now has a local clear text password, which it needs this to do the salting and hashing. But a persistent intruder can grab the unencrypted password, and send it with the user name any other account details to an external site. Bad news, all active users are at full risk.

The answer is to have the local web page do a preliminary hash of the password. That locally generated hash is then sent to the website, which is then salted and hashed again, and that value is what is stored in the database.

It sounds easy, but there are several complications to consider.

  • A user that uses a simple password is still at risk as if they had no hashing, where a rainbow table (a pre-generated database of common passwords and their hashes) can be used in near real-time. The local user needs to salt (append a unique but known string), so the server must supply a salt. Don’t forget to store both the local salt and a server salt in your database.
  • You need a JavaScript routine to perform the hash since you can’t use a server side or database function, like this or this or this. Also, you need to be absolutely sure the code behaves the same on all browsers.
  • If using a simple <input type=”passowrd”> HTML control you need to be sure to blank it out prior to submitting or else the plain text will go through anyway.

Are there any downsides? Unfortunately I can think of a couple.

  • Hopefully your clients don’t run IE 6.0 or it could take a while to run. Old Javascript interpreters can be 100x slower or worse.
  • Many browsers offer to save your user name and password upon submission, but if the hashing Javascript is blanking out the password field upon completion then the browsers won’t be able to store the password. This also impacts third party plugins like LastPass.

So are you secure at this point? Well, you’re much better off.

  • An intercepted hash can be hacked into a submitted web page as credentials, allowing a bad guy to log into your site as a user through the front end. However the hash cannot be converted back into a password or used to attack an individual’s other Internet logins.
  • An intercepted hash can be used to change that user’s password, but again, it doesn’t recover the original password.
  • But don’t forget the big one: You’ve got a persistent intruder in your network!

I don’t know of any published persistent attacks that do this, but as more companies start complying with best practices, I have no doubt the bad guys will try tactics like this. Best to stay one step ahead in the arms race.

UPDATE: Thanks Darren, I’ve just read the Sony security update. I’m very glad to hear Sony is hashing the passwords, so yeah, the protagonist for my narrative is no longer valid. Thats OK, blogs are snapshots in time, but since it is a correction it should be a post update instead of a comment response.