Eliminating session hijacking... forever
Jim Manico, over at Manicode, is doing an interesting thing: he is trying to convince the maintainers of every web application stack component everywhere (e.g. browsers, web servers, libraries) to implement the HttpOnly mechanism (read more on HttpOnly in Mitigating Cross-site Scripting With HTTP-only Cookies). Actually, he is doing more than that—in many cases he is fixing things himself and submitting the patches. It's his HttpOnly Crusade.
The general idea behind HttpOnly is to prevent the disclosure of session tokens to JavaScript, which would, in turn, reduce the likelihood of session hijacking attacks. It's a noble idea, but one which is very difficult to succeed. The problem is that we are dealing with a leaky bucket. HttpOnly deals with one of the leaks, but it doesn't do anything about the others. And there are many leaks to take care of. If you go through Jim's blog posts, you will find that AJAX requests will also need tweaking (to hide the cookies marked with HttpOnly), and there is not even mention of session tokens embedded in request URIs, or embedded in request parameters. There is no doubt that an implementation of HttpOnly in all software components would raise the bar and make us more secure, but it won't solve the problem. In this particular case I would prefer to replace the entire bucket.
Our real problem is that session management is not standardised, forcing every application platform (and many applications) to provide its own implementation. Why is this bad?
- Implementing session management correctly is not trivial. First versions of many implementations have been found to be incorrect and, thus, insecure.
- It's a waste of time. Session management is best abstracted and handled by the underlying platform or library.
- Application-level implementations of session management (all implementations today) are inherently vulnerable to session hijacking. We must move session management to a different layer in order to be able to implement it securely (see below).
Why is session hijacking possible in the first place? The HTTP authentication model, as originally envisioned, is not vulnerable to session hijacking because it requires authentication on every request. Session tokens are still needed to identify which requests are part of a session, but since authentication always take place there can be no hijacking. The HTTP authentication model was lacking in many other respects (e.g. there were no provisions to log people out, expire sessions, and so on), so most people simply decided not to use it. In the currently dominant session management model authentication is done only once per session, which turns session tokens into time-limited password surrogates, and thus valuable. Anyone who knows a session token can resume the session it refers to.
There are two ways to solve the session hijacking problem cleanly:
- Perform authentication on every request, thus making session tokens worthless (as far as hijacking is concerned). You can do this today in certain circumstances, for example if you are willing to use any of the HTTP authentication methods (Basic or Digest), or if your application uses client SSL certificates (in this case all you need to do is to attach the client's SSL certificate to the session, and check that it is the same on every subsequent request).
- Start a new RFC effort to define session management, and then implement it in a layer other than HTTP. We already have the ideal candidate for this function—SSL. SSL actually already understands sessions (they were added to version 3 to increase performance) so only a few tweaks would be needed to make the mechanism suitable for web applications.