Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Signed session cookies. A good idea?

In an effort to increase performance, I was thinking of trying to eliminate a plain 'session cookie', but encrypt all the information in the cookie itself.

A very simple example:

userid= 12345 time=now() signature = hmac('SHA1',userid + ":" + time, secret);  cookie = userid + ':' + time + ':' + signature; 

The time would be used for a maximum expirytime, so cookies won't live on forever.

Now for the big question: is this a bad idea?

Am I better off using AES256 instead? In my case the data is not confidential, but it must not be changed under any circumstances.

EDIT

After some good critique and comments, I'd like to add this:

  • The 'secret' would be unique per-user and unpredictable (random string + user id ?)
  • The cookie will expire automatically (this is done based on the time value + a certain amount of seconds).
  • If a user changes their password, (or perhaps even logs out?) the secret should change.

A last note: I'm trying come up with solutions to decrease database load. This is only one of the solutions I'm investigating, but it's kind of my favourite. The main reason is that I don't have to look into other storage mechanism better suited for this kind of data (memcache, nosql) and it makes the web application a bit more 'stateless'.

10 years later edit

JWT is now a thing.

like image 814
Evert Avatar asked Jul 13 '10 18:07

Evert


People also ask

Should I Always allow session cookies?

There's just no good reason to ever allow sites and servers you don't intentionally visit to plant cookies onto your computer. For Always allow session cookies: This should always be disabled (not checked).

Are session cookies safe?

Session cookies store information about a user session after the user logs in to an application. This information is very sensitive, since an attacker can use a session cookie to impersonate the victim (see more about Session Hijacking).

What is the significance of a signed cookie?

If the cookie is a signed cookie and signature can be validated, then it will return the parsed unsigned value. If the cookie is unsigned, then the original value is returned. If the cookie is signed but the signature cannot be validated, then false is returned.

Is it better to use session or cookies to manage login authentication data?

Session is safer for storing user data because it can not be modified by the end-user and can only be set on the server-side. Cookies on the other hand can be hijacked because they are just stored on the browser.


2 Answers

A signed token is a good method for anything where you want to issue a token and then, when it is returned, be able to verify that you issued the token, without having to store any data on the server side. This is good for features like:

  • time-limited-account-login;
  • password-resetting;
  • anti-XSRF forms;
  • time-limited-form-submission (anti-spam).

It's not in itself a replacement for a session cookie, but if it can eliminate the need for any session storage at all that's probably a good thing, even if the performance difference isn't going to be huge.

HMAC is one reasonable way of generating a signed token. It's not going to be the fastest; you may be able to get away with a simple hash if you know about and can avoid extension attacks. I'll leave you to decide whether that's worth the risk for you.

I'm assuming that hmac() in whatever language it is you're using has been set up to use a suitable server-side secret key, without which you can't have a secure signed token. This secret must be strong and well-protected if you are to base your whole authentication system around it. If you have to change it, everyone gets logged out.

For login and password-resetting purposes you may want to add an extra factor to the token, a password generation number. You can re-use the salt of the hashed password in the database for this if you like. The idea is that when the user changes passwords it should invalidate any issued tokens (except for the cookie on the browser doing the password change, which gets replaced with a re-issued one). Otherwise, a user discovering their account has been compromised cannot lock other parties out.

like image 128
bobince Avatar answered Oct 06 '22 04:10

bobince


I know this question is very old now but I thought it might be a good idea to update the answers with a more current response. For anyone like myself who may stumble across it.

In an effort to increase performance, I was thinking of trying to eliminate a plain 'session cookie', but encrypt all the information in the cookie itself.

Now for the big question: is this a bad idea?

The short answer is: No it's not a bad idea, in fact this is a really good idea and has become an industry standard.

The long answer is: It depends on your implementation. Sessions are great, they are fast, they are simple and they are easily secured. Where as a stateless system works well however, is a bit more involved to deploy and may be outside the scope of smaller projects.

Implementing an authentication system based on Tokens (cookies) is very common now and works exceedingly well for stateless systems/apis. This makes it possible to authenticate for many different applications with a single account. ie. login to {unaffiliated site} with Facebook / Google.

Implementing an oAuth system like this is a BIG subject in and of itself. So I'll leave you with some documentation oAuth2 Docs. I also recommend looking into Json Web Tokens (JWT).

extra

A last note: I'm trying come up with solutions to decrease database load. This is only one of the solutions I'm investigating

Redis would work well for offloading database queries. Redis is an in memory simple storage system. Very fast, ~temporary storage that can help reduce DB hits.

like image 37
Cody Wikman Avatar answered Oct 06 '22 04:10

Cody Wikman