> it's common practice (e.g. in Rails' cookie store, but many others too) to leave the cookie contents as plaintext and just append a HMAC so that you know they haven't been tampered with.
This approach seems strange to me. Why is this approach taken? Why not encrypt everything?
I only really know anything about writing server-side web code from using Play Framework, which provides a "session" object for storing information in the browser using the cookies mechanism. Everything in the session object is kept encrypted on the client in a cookie.
The most common use for the session information is to store a user ID and/or a session ID, but I believe it not uncommon to use this to store additional small bits of information if this will take some load off of your database and/or cache, and to help the server be more RESTful/stateless.
Edit: It turns out that I was not quite correct about Play. Like Rails, it seems to only sign the session cookie, rather than encrypting it. From looking at some benchmarks for the performance of HMAC vs Blowfish, it seems that signing with HMAC can be up to 4X faster than encrypting with Blowfish.
It is based on the observation that most apps only store the user ID and other non-sensitive data in the session. Storing the session in the cookie then brings many benefits. It does not require any server side session store maintenance, it is very fast and scalable because no database lookup is required. The fact that this store should not be used for storing sensitive information is well-documented in the Rails security guide. For storing sensitive information, one can use many of the alternative session stores available, such as the ActiveRecord session store which saves session data into the database.
We at Phusion have created an encrypted session store in the past (http://blog.phusion.nl/2010/04/13/announcing-encryptedcookie...). However we've found it to be of limited use (and indeed, it doesn't look like many people use it). If your data is sensitive then you're better off storing it on the server. If your data is not sensitive then encrypting it doesn't help you.
I dont know either why is this the default in rails.
In PHP you only have a session id in a cookie. When I first saw how it works in rails (ruby?) it blew my mind.
I don't want to think about how many rails user don't know this and send sensitive data to the client.
The advantage -- and it's often a big one -- is that you don't have to have a corresponding server component to translate session id to session state. The state is all in the client.
Edit: wouldn't have written this if I'd seen FooBarWidget's more detailed remarks first.
The session information is cryptographically signed, so you don't have to trust it! These stateless server frameworks are just using the client as a state cache.
The information is usually already publicly available : for examples the facebook graph api uses the same setup for some of their basic api methods (such as letting a site log you in through facebook) - base64 encoded json user data and an hmac signed with a private key + timestamp. Since the data is already publicly available (it's your facebook user id and other publicly available data), there's no need to use a more costly encryption algorithm. The hmac is there to confirm to the server who manages whichever associated online service that also created a facebook app you just gave access your profile to that this is good data, since they've got the secret on their end that the staff registered with on facebook. HMAC is fast.
No, it doesn't. No one should be using Blowfish for anything (except its key scheduler for bcrypt) and Blowfish is known to be slow as hell. A SHA-2 HMAC is basically identical in speed to AES-CTR. Sure, you want an HMAC on that, too, but whatever -- get a modern processor or an AES coprocessor. I guarantee this is not your performance bottleneck.
>The most common use for the session information is to store a user ID and/or a session ID, but I believe it not uncommon to use this to store additional small bits of information if this will take some load off of your database and/or cache, and to help the server be more RESTful/stateless.
This approach seems strange to me. Why is this approach taken? Why not encrypt everything?
I only really know anything about writing server-side web code from using Play Framework, which provides a "session" object for storing information in the browser using the cookies mechanism. Everything in the session object is kept encrypted on the client in a cookie.
The most common use for the session information is to store a user ID and/or a session ID, but I believe it not uncommon to use this to store additional small bits of information if this will take some load off of your database and/or cache, and to help the server be more RESTful/stateless.
Edit: It turns out that I was not quite correct about Play. Like Rails, it seems to only sign the session cookie, rather than encrypting it. From looking at some benchmarks for the performance of HMAC vs Blowfish, it seems that signing with HMAC can be up to 4X faster than encrypting with Blowfish.