By now, we should all know to use bcrypt or scrypt to store salted password hashes with a sufficient number of rounds. (See, e.g., https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet) The lesson: assume your authentication database will be compromised at some point.

We should also all know how to design user authentication cookies that meet the level of security and confidentiality our application requires using HMACs with per-user keys. The most often-cited paper I've seen is http://www.cse.msu.edu/~alexliu/publications/Cookie/cookie.pdf.

However, every paper and proposal I've read that tackles secure user authentication addresses a different, overlapping set of concerns (eg, eavesdropping, tampering, & replay attacks) and are often aimed at storing opaque-to-the-user data too.

I can't find any that address how to make client-side user authentication cookies resistant to attack even after the server's authentication database has been compromised.

The above paper, for example, just relies on the secrecy of the server's key. Many implementations I've seen also generate a per-user token that is used in the HMAC and stored on the server. In either case, once the server secret is compromised, it's trivial to forge any user's credentials.

Are there any references or known implementations that cover this scenario for typical web applications (i.e., outside of corporate and banking environments)?

1 Answer 1


If the whole server is compromised, then whatever the server can do, the attacker can, too.

Therefore, the only way to have a user authentication which resists past a total server compromise is to base that authentication on something which the user can do, but which the server cannot, but such that the server can verify that the user is doing it. This calls for a digital signature. The user should somehow store a private key somewhere on his machine, and use it to sign some sort of challenge sent by the server.

The private key should not be accessible from Javascript; otherwise, the attacker could plant some Javascript code which would retrieve the user's private key. In a Web context, digital signatures but without code sent by the server, this points at user certificates.

This can be done. Moreover, this is done (I have seen it used by some banks, issuing certificates to their customers). SSL supports client-side certificates and recent browser versions have become almost user-friendly when it comes to using them. You could even distribute smartcards (or equivalent gadgets which plug in a USB port, to make installation easier).

  • That's good for banking and corporate environments. Is there no way to provide attack resistance for a typical web application? I understand the security benefits of a private key that's not accessible to Javascript and not ever sent to the server. Is there a middle ground with a (server-generated) user client key that's combined with the server key to generate an HMAC, where the server never persists the user client key (only uses it temporarily for computation when validating the credentials)?
    – Michael
    Oct 5, 2012 at 19:34
  • @Michael: this would be equivalent to generating a random, hidden password, sending it to the client as a cookie, and storing a hash of it server-side. This would work if the server total compromise is a server total read-only compromise (the attacker gets a copy of everything but changes nothing). I don't find it a very realistic scenario. Oct 5, 2012 at 19:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .