Friday, October 23, 2009

Cookies best practices: Cookies, WebSphere, LTPA, Single Sign-On

Yesterday I had to debug a strange problem that was affecting our security infrastructure. It seemed as though, despite being transmitting a Single Sign-On token as a cookie to web applications, they couldn't gain access to some protected resources any more. We're using an IBM DataPower SOA Appliance to implement the user registry and the LTPA (Lightweight Third Party Authentication) token generation and the IBM WebSphere Application Server is configured to accept a Single Sign-on LTPA token. Nothing in the WebSphere Application Server configuration had changed and very little diffs were applied to our DataPower appliance in the testing environment. Despite the changed code was easy to double check, we immediately thought about a cookie-related problem and troubleshooting was straightforward, luckily.

I think it's worth describing what was going on because I often felt common misconceptions, or simply not enough knowledge, about cookies.

What a cookie is

Cookies were invented by venerable Netscape Corporation as a very first mean of providing some sort of state to an otherwise stateless protocol, such as HTTP is. Nowadays we're used to interacting with stateful web applications. That illusion is brought to us by some sort of an user session implementation in web and application server where such applications are run: as far as it concerns the web server, each one of the HTTP requests originating from our web browser isn't distinguishable to previous ones we might have done. The correlation is done on the server side by means of the information our browser (usually a session ID) sends along with the HTTP requests. Cookies were invented to solve this problem, although nowadays some application server may rely on other techniques: a piece of information our browser attaches on the HTTP request (in the form of a header). Cookies structure and behavior is described in RFC-2965.

Cookie behavior is pretty simple: they're simple text structure, they have a name, they might have an expiration date, they might specify whether they're meant to be sent on an encrypted connection only, they have a domain and a path and an arbitrary bucket of name-value pairs.

When the browser sends a cookie

Cookies, obviously, aren't indiscriminately attached to every HTTP requests originating from your browser. If a cookie is valid (has not expired) the browser send a cookie back with an HTTP request if the request is directed to the cookie domain to a resource contained in the cookie path. If a cookie's domain is www.example.com, it won't be sent back with a request to another.example.com. because the domains differ. Nor will a cookie be sent to www.example.com/pages/resource.jsp if the cookie path is /protected.

Pros and cons

Cookie domain and path are a powerful mechanism to isolate your cookie and avoid useless server resources' consumption analyzing cookie that are not used by specific applications. Setting a path correctly can help you avoid cookie attribute clashes (same name, domain and path) and restrict cookie usage only in the application that generates them. In the Java EE world, for example, an application could set a cookie's path to the context path of the Java EE web module so that the cookie is never sent to any other application. You might also decide to use a sub-path inside your own application to lower the request size, avoid processing of unnecessary information and lower the chances that cookies might be used in circumstances they weren't designed for. On the other hand, to implement basic inter-application communication, you might decide to just use the / path so that a cookie may be shared by more than one application in the same domain.

In any case, although this article is not about cookies security practices, I'll warn you against using cookies to store sensitive information, unless you implement the necessary precautions (for example, by using them on encrypted connections only).

The solution

The solution of our problem was trivial: because of a glitch, an LTPA token was being transmitted on a cookie whose path wasn't /. Being a Single Sign-On token in a Java EE environment deployed upon instances of IBM WebSphere Application Server, it was essential that the LTPA cookie was received by the application server when accessing protected resources of every application in the same realm. Setting the path to any other subdirectory was defying the Single Sign-On token purpose. WebSphere was correctly redirecting us to our corporate login page just because the cookie wasn't included in the request when jumping from one application to another.

No comments: