This is a very common problem in a lot of signed cookie based session stores. Some frameworks get it right, some don't.
The best remediation is to include an expire timestamp within the content of the signed cookie and to check this on the server - you can't rely on the client deleting the cookie (never trust the client).
The guys at GitHub fixed this particular issue in their rails stack, and submitted a pull request 4 months ago:
It started out well, and their proposed solution would have fixed this problem. The thread got bogged down in discussing backwards compatibility and the original submitter just gave up on it.
I hope this might trigger somebody to pick that pull request up again and get it sorted and merged.
Since signed cookies are now a popular form of persisting session state I have been meaning to run through all the popular web app frameworks to check this issue.
edit: check out TimedSerializer from the itsdangerous Python library that Flask uses:
The solution I use in my own application is for each cookie that gets set to be a distinct, random shared secret that is mirrored in a database table.
The shared secret is the combination of a near-random string of bytes generated by a hash of numerous things, plus a unique ID generated upon insert into the database table. The secret survives in the table until the user chooses to sign out, or until the cookie expires. Once the secret is expired, the cookie is useless.
This also means users can go into their account page to see on which devices their account has been remembered, but also to log out any/all other sessions.
>..random shared secret that is mirrored in a database table.
Isn't the point of using a cookiestore to avoid hitting the database and thus eliminating the need for the painful session/state maintenance across multiple nodes? Your solution looks more like a DIY security solution to me, (please correct me if I'm wrong) and I would take major precautions in gambling with security-related functions of a framework.
P.S I am confused, please explain if I am wrong, I will gladly rather be corrected than make a possibly serious security mistake in one of my own applications.
> eliminating the need for the painful session/state maintenance across multiple nodes
If session/state maintenance across nodes is painful, the solution isn't to trust the web browser, it's to make such maintenance much less painful. For example, you can use a cache server (like ehcache) to store session state. Or you can use smarter load balancers (like haproxy) to minimize node hopping.
A cookie is an authentication credential, just like a username and password combination. If you can't invalidate an authentication credential on the server side, your solution is an instant fail.
I like to ensure that the key used to sign the sessions is rotated on a regular basis. On Heroku, for example, there is the Secure Key[0] addon which takes care of this for you.
The best remediation is to include an expire timestamp within the content of the signed cookie and to check this on the server - you can't rely on the client deleting the cookie (never trust the client).
The guys at GitHub fixed this particular issue in their rails stack, and submitted a pull request 4 months ago:
https://github.com/rails/rails/pull/11168
It started out well, and their proposed solution would have fixed this problem. The thread got bogged down in discussing backwards compatibility and the original submitter just gave up on it.
I hope this might trigger somebody to pick that pull request up again and get it sorted and merged.
Since signed cookies are now a popular form of persisting session state I have been meaning to run through all the popular web app frameworks to check this issue.
edit: check out TimedSerializer from the itsdangerous Python library that Flask uses:
https://github.com/mitsuhiko/itsdangerous/blob/master/itsdan...