Session Management – Storing Session Key in a Hidden Field

designjquerysession

Background:

I have a question which is outline at Use different local storage between windows. The very high level question is "How can I keep tabs and windows sessions from clashing".

Requirement:

I want to be able to have separate "sessions" for each tab(s) or window(s).

Problem:

The problem is if I store the data in cookies or in HTML Local Storage, it will be very difficult prevent the user from screwing up the data by opening s new window or tab and keeping the data separate.

Possible Solution:

Since Tabs and Windows share cookies and HTML Local Storage under the same instance. My question to here is, how safe is it to store a unique key in a hidden field to use to retrieve the cookies or HTML Local Storage? By doing it this way, if a new page is created (or Tab), this field is not shared across tabs and windows. What's the security risk in this approach and its a good idea?

For example, I would store the session id or Key in a hidden field:

  <input type="hidden" name="sessionId" id="sessionId" value="" />

Best Answer

Cookies are primarily attractive because of the ability to store long-lived values and the convenience of not having to explicitly submit session identification with each request (because the browser will). You can also pretty effortlessly hide cookie values from scripts, whereas the same protection over a form field or variable requires a more verbose solution.

But, since you'll probably be rolling your own session management library, you'll need to be aware of a few things -- probably more than I have listed here -- but as a start, you need to protect against:

  • Predictable session ID's which may allow users to "find" and hijack another
  • Allowing users to provide their own Session ID; only ID's generated by the server should be recognized
  • Allowing scripts to see the session ID

The first two concerns apply to any type of session. They're notable largely because you'll likely be rolling some custom session management code. The third concern applies much more-so, but not exclusively, to cookieless sessions, because cookie headers can be flagged as http-only cookies.

To prevent scripts from seeing a value, you need to close over the ID with some care:

var SessionScope = (function() {
  var o = {};

  // outside scripts can't see this:
  var session_id = '1234';

  // these methods can see session_id and use it to channel/sign requests
  o.get = function(url, data) { };
  o.post = function(url, data) { };
  o.whateverelse = function() { };

  return o;
})();

To be clear, you ideally need to ensure that the SessionScope (or whatever) is built in such a way that it doesn't even have ties to a constructor that could be toString()'d.

Now, I understand the risk of letting scripts see your session ID's to be pretty low in most cases. It becomes most problematic when you display data submitted by one user to another user, or when you incorporate less-than-trustworthy 3rd party libraries. That said, if you go this route, it's perfectly feasible to add the extra protection, so you should.

And again, you'll want to consider that, if you depart from storing session ID's in cookies, you'll likely either lose or impede the ability to reattach to the session without asking the user to "find" it in some way.


With all of that said, you may not actually want distinct "sessions" at all. The best solution may still just be a single session. If your user is logged in using the same credentials and permissions on each tab, and you need to track data related to a particular window, tab, or view on both the client and server, you probably just want a collection in the session. But in that type of solution, view/tab identifiers aren't usually necessary because the view only asks for things relevant to itself.

Cross-talk between tabs and views is avoided by a combination of keeping things out of the "global" session that don't belong there and only asking for things you need.

But, if that's not feasible for some reason, you could consider adding a collection of view collection to your session model and passing a viewid around. In this case, you wouldn't have to worry about all the security concerns of session key management and protection (assuming you're properly using a strong session system). The view keys would only be relevant to the session, so a leaked viewid isn't relevant to anyone else, and therefore not a significant threat.

Related Topic