Software and Other Mysteries

On code and productivity with a dash of unicorn dust.

Don't Forget Me, Cookie!

Most websites where authentication is required to perform certain actions have the option of remembering your credentials. Convenient, indeed, but bypassing the user input phase of the login means some other type of identifier needs to be stored locally which could pose a severe security risk.

My first attempt at this - and please remember this was a long, looong time ago, in a simpler time - was to simply store the username and password in a cookie. Yes, that’s right, store the user’s credentials in plain text. The security concerns are obvious, a simple cookie theft would give the attacker everything he needs without having to think twice, and as if that wasn’t enough there is a high risk that the same credentials can be used to access other sites since very few people actually use different passwords for every site they register on. Luckily this site never reached an audience..

By storing the password hash we will at least take care of the leaked credentials issue, as long as we use a decent hash algorithm and salt the password properly (a simple md5 is not good enough, but more on this another time), thereby taking the likes of simple dictionary attacks out of the equation. The attacker can still access the account however.

Fact is that a compromised “remember me”-cookie will always allow an attacker to gain access to the account to which the cookie belongs. What we want to do is mitigate the impact. For example, we want to make sure that a malicious user cannot access someone else’s account and lock them out by changing the password. For these types of actions that concern the privacy and security of the user we want to make sure that the authenticated user actually knows the password. As long as we do this, the above is a pretty decent solution.

An even better, though slightly more advanced, solution is to never even store the password, hashed or not, in the cookie. Instead a randomly generated token can be stored in the client cookie as well as in the application database upon login. The next time that same browser visits the site the token and username/user ID, whichever you prefer, from the cookie can be checked against the server and if they match we have a valid login. This is a very brief summary of the points made in Charles Miller’s post Persistent Login Cookie Best Practice and Barry Jaspan’s improvement of the same in Improved Persistent Login Cookie Best Practice. This is about as safe as you can get as far as remembered logins go.

The point I really want to make is that there is no perfect solution for this and you should bear in mind that for any site requiring a high level of security a “remember me”-option is a big no-no, plain and simple. For any other site it’s a decision that must be made by you as a developer, weighting user convenience against any security implications.