3 ms·
The idea of storing sensible stuff client side is indeed powerful and very simple. The problem is the client could change this state, and in most applications t
by antirez 17y ago
The idea of storing sensible stuff client side is indeed powerful and very simple. The problem is the client could change this state, and in most applications this is not a cool idea, so it's just a matter of signing it.
Assuming we want to store "foobar" client side, and make sure the client can't change this, all we need is to have a server-side-secret, that is, a random string that can't be guessed from outside. Get it with this:
dd if=/dev/urandom bs=1 count=512 | md5sum
Well now just we can set the cookie as
"foobar|"+sha1_hmac("foobar","ServerSideSecret").
There is no way the user can alter the cookie, otherwise the signature will no longer match. But often there are other kind of attacks: for example the user can get the cookie from another user, and in the context of the wrong user id the cookie content can be dangerous.
Another common condition is that this information should only be valid for a given amount of time.
To fix both this problems just add to the string to sign the current unix time and the user id, so the final cookie will be (assuming 100 is the user id):
"foobar|1244498681|100|"+sha1_hmac("foobar|1244498681|100","ServerSideSecret")
When you check the cookie back, make sure to compare the server unix time with the timestamp in the cookie. If it's older than N seconds just ignore it.
Another common trick is to add the user IP address to the string in order to avoid that the cookie can be reused in the context of a different IP.
This stuff are very cool to save CPU time in your servers but make sure to think about all the kind of attacks like playback attacks or sending the cookie in other contexts, users, IP, time, applications (if you share secrets), and so on.
- jjs 17y agoI like to stick the hmac hash at the beginning of the cookie text, since it has a known length. I don't care about tampering on the client-side (since you could achieve the same effect with firebug), so js scripts can simply lop off the first n characters and use the rest of the cookie text as-is.