Cookie-based sessions: why HMAC?

(apologies if this goes through multiple times, it’s been almost 24 hrs and I haven’t seen my original post)

First of all, I love the new cookie-based sessions. Thanks bitsweat. I just have an architectural question / suggestion.

The CookieStore takes great care to provide integrity of session data, but we seem to have lost confidentiality in the process. The server-side storage methods had the implicit advantage of keeping the session data secret, but I don’t know if this was intentional or just an unintended consequence.

Would anyone see a disadvantage to symmetrically encrypting the cookie data rather than signing it with an HMAC?

As far as I can think, this would retain all of the benefits of the current arrangement while obscuring the session data from a potentially untrusted client. (Not that untrusted-client is the normal way of things, but I tend to think fail-secure.) I don’t think we need the full authenticity that an HMAC provides, since we’re not trying to prove session authenticity to anyone other than the server that generated the session.

Thanks!

–be

You'd still need to do the HMAC also, otherwise they could modify the session. Even if they're modifying in the dark, they could cause funny things to happen (eg imagine storing an id of a model which will be deleted...) - witness what happened to WEP when they forgot this.

I agree with you that this should be an option. But I think that even symmetric encryption is much slower than a simple HMAC - so there would be a performance hit.

Brad Ediger wrote:

I thought about the integrity issue, but wouldn’t it be sufficient to just prepend a known string to the data and verify it on thaw?

According to this page (http://www.cryptopp.com/benchmarks.html), SHA-1 and AES are about equal in speed (SHA-1 is marginally faster). But I would guess that in this situation even an order of magnitude difference probably wouldn’t matter. (Warning: unsubstantiated claim!)

I just noticed that the RDoc does make the nonconfidentiality assumption explicit, so this is probably less of an issue than I had originally thought.

I thought about the integrity issue, but wouldn't it be sufficient to
just prepend a known string to the data and verify it on thaw?

Not always. This is getting into very difficult crypto. Basically, depending on the cipher, there may be cases where you can change one part of the text without changing the other.

WEP tried to do the trick you're talking about - for performance - and got nailed. There's no reason to open up a can of worms like this. If you want integrity, you need a good HMAC.

The CookieStore takes great care to provide integrity of session data, but we seem to have lost confidentiality in the process. The server-side storage methods had the implicit advantage of keeping the session data secret, but I don't know if this was intentional or just an unintended consequence.

My first cut used symmetric encryption. It's a bit slower than HMAC, but both push thousands of ops/sec on my laptop so it's not really a concern.

The typical session stores a handful of utilitarian info: a user_id, a flash message, and perhaps a return URL. You shouldn't, and needn't, use the session for confidential data.

I consider exposing these data (however obfuscated) as statement of the reasonable bounds of session usage.

Would anyone see a disadvantage to symmetrically encrypting the cookie data rather than signing it with an HMAC?

There isn't much technical disadvantage, though it loses HMAC's in-the-clear philosophical advantage.

However, the cookie store is built to be easily subclassed; please do investigate!

jeremy

I fold. :slight_smile: There's no easy and elegant way to fix this other than to clarify the assumption.

The CookieStore takes great care to provide integrity of session data, but we seem to have lost confidentiality in the process. The server-side storage methods had the implicit advantage of keeping the session data secret, but I don't know if this was intentional or just an unintended consequence.

My first cut used symmetric encryption. It's a bit slower than HMAC, but both push thousands of ops/sec on my laptop so it's not really a concern.

The typical session stores a handful of utilitarian info: a user_id, a flash message, and perhaps a return URL. You shouldn't, and needn't, use the session for confidential data.

I consider exposing these data (however obfuscated) as statement of the reasonable bounds of session usage.

Couldn't agree more, from a philosophical standpoint. And I've never had need to put anything more than the above into a session. I was just looking for an easy way to failsafe the API against someone who decides to use session[:credit_card_number]. Apparently there isn't an easy way, and such people get what they deserve. :slight_smile:

Would anyone see a disadvantage to symmetrically encrypting the cookie data rather than signing it with an HMAC?

There isn't much technical disadvantage, though it loses HMAC's in-the-clear philosophical advantage.

Well, I was wrong about the technical disadvantage. See my discussion with S. Robert James in this thread. I'd rather have one big well-known weakness that people can code around than a few lurking ones.

I'll transplant parts of this discussion into my Rails book to make this more explicit, especially since CookieStore is the default now.

Great job, by the way. It's an elegant solution to a nasty little problem.

Brad

The typical session stores a handful of utilitarian info: a user_id, a

flash message, and perhaps a return URL. You shouldn’t, and needn’t, use the session for confidential data.

I consider exposing these data (however obfuscated) as statement of the reasonable bounds of session usage.

Storing the user_id in a cookie is exactly the sort of security hole that does concern me. What steps have been taken to ensure that the data cannot be tampered?

I also agree that rails should be secure by default. If the data is in text format, then I think session cookies by default is an unwise choice.

Steven A Bristol

Storing the user_id in a cookie is exactly the sort of security hole that does concern me. What steps have been taken to ensure that the data cannot be tampered?

That's what the HMAC is for, if you tamper with the data, the hash is no longer correct.

I also agree that rails should be secure by default. If the data is in text format, then I think session cookies by default is an unwise choice.

I don't believe there's a single person on this list who thinks we should ship security bugs. If there's a genuine problem with the cookie store, we'll take the actions needed to clean it up.

The HMAC ensures that. (HMAC - Wikipedia) If the user tampers with the data, the MAC verification fails and the server rejects the session.

This discussion is about situations where confidentiality might be required -- where you might want to store something in the session that you don't want the user to be able to read.

Not really knowing much about the new cookie storage for sessions, is the session effected if I set cookies in javascript on the client machine?

Short answer: don't do that with cookie based sessions.

Always remember what sessions are - an abstraction that gets around the stateless nature of HTTP. It's merely there so that you know that the HTTP request has come from somebody you've dealt with recently. That's it.

It should contain the minimum amount of data necessary to identify where you are in the transaction sequence - assuming the information from the URL supplied is insufficient to do that on its own.

Beyond that you are polluting the session layer with application concerns, for which you must expect to be smited by the Gods of Programming :slight_smile:

NeilW

Read the rest of the thread. I agree with you completely. :slight_smile:

guid field instead of database IDs will mitigate some of your concerns

    @user = User.find_by_guid(session[:user_id])

court3nay