How do you configure HttpOnly cookies in tomcat / java webapps?

Solution 1:

httpOnly is supported as of Tomcat 6.0.19 and Tomcat 5.5.28.

See the changelog entry for bug 44382.

The last comment for bug 44382 states, "this has been applied to 5.5.x and will be included in 5.5.28 onwards." However, it does not appear that 5.5.28 has been released.

The httpOnly functionality can be enabled for all webapps in conf/context.xml:

<Context useHttpOnly="true">
...
</Context>

My interpretation is that it also works for an individual context by setting it on the desired Context entry in conf/server.xml (in the same manner as above).

Solution 2:

Update: The JSESSIONID stuff here is only for older containers. Please use jt's currently accepted answer unless you are using < Tomcat 6.0.19 or < Tomcat 5.5.28 or another container that does not support HttpOnly JSESSIONID cookies as a config option.

When setting cookies in your app, use

response.setHeader( "Set-Cookie", "name=value; HttpOnly");

However, in many webapps, the most important cookie is the session identifier, which is automatically set by the container as the JSESSIONID cookie.

If you only use this cookie, you can write a ServletFilter to re-set the cookies on the way out, forcing JSESSIONID to HttpOnly. The page at http://keepitlocked.net/archive/2007/11/05/java-and-httponly.aspx http://alexsmolen.com/blog/?p=16 suggests adding the following in a filter.

if (response.containsHeader( "SET-COOKIE" )) {
  String sessionid = request.getSession().getId();
  response.setHeader( "SET-COOKIE", "JSESSIONID=" + sessionid 
                      + ";Path=/<whatever>; Secure; HttpOnly" );
} 

but note that this will overwrite all cookies and only set what you state here in this filter.

If you use additional cookies to the JSESSIONID cookie, then you'll need to extend this code to set all the cookies in the filter. This is not a great solution in the case of multiple-cookies, but is a perhaps an acceptable quick-fix for the JSESSIONID-only setup.

Please note that as your code evolves over time, there's a nasty hidden bug waiting for you when you forget about this filter and try and set another cookie somewhere else in your code. Of course, it won't get set.

This really is a hack though. If you do use Tomcat and can compile it, then take a look at Shabaz's excellent suggestion to patch HttpOnly support into Tomcat.