Sunday, March 9, 2008

HTTPOnly support for Apache Tomcat

I've made specific suggestions to the Apache Tomcat core developer team to add HTTPOnly support to Tomcat 5.5 (for starters). The adoption is slow-going since it involves changes to three of the most core files of Tomcat.
Here is how you can get HTTPOnly support NOW while you wait for official adoption.

1) First download the Tomcat source code and be able to build the core server via ANT. See http://tomcat.apache.org/tomcat-5.5-doc/building.html for instructions. Although the link above points to Tomcat 5.5, the changes I'm suggesting below will work for any Tomcat build.

Once you have downloaded the Tomcat code and have set up your build environment, you will need to make the following changes to at least org.apache.catalina.connector.Request.java and org.apache.catalina.connector.Response.java. You could (should) also make changes to org.apache.tomcat.util.http.ServerCookie.java if you require a very scalable solution where every StringBuffer.append matters; but that addition is beyond the scope of this post.

2) org.apache.catalina.connector.Request.doGetSession(boolean create) is where the session cookie (JSESSIONID) is initially created. You are going to need to change this. This first change is at approximately loc 2321 of the file org.apache.catalina.connector.Request.java (for Tomcat 5.5).

//this is what needs to be changed
//response.addCookieInternal(cookie);

//this is whats new
response.addCookieInternal(cookie, true);
}

3) In order to support the new HTTPOnly version of Response.addCookieInternal, we need to modify the functionality of org.apache.catalina.connectorResponse.addCookieInternal. The following are my suggested backward-compatible changes:

public void addCookieInternal(final Cookie cookie) {
addCookieInternal(cookie, false);
}

public void addCookieInternal(final Cookie cookie, boolean HTTPOnly) {

if (isCommitted())
return;

final StringBuffer sb = new StringBuffer();
//web application code can receive a IllegalArgumentException
//from the appendCookieValue invokation
if (SecurityUtil.isPackageProtectionEnabled()) {
AccessController.doPrivileged(new PrivilegedAction() {
public Object run(){
ServerCookie.appendCookieValue
(sb, cookie.getVersion(), cookie.getName(),
cookie.getValue(), cookie.getPath(),
cookie.getDomain(), cookie.getComment(),
cookie.getMaxAge(), cookie.getSecure());
return null;
}
});
} else {
ServerCookie.appendCookieValue
(sb, cookie.getVersion(), cookie.getName(), cookie.getValue(),
cookie.getPath(), cookie.getDomain(), cookie.getComment(),
cookie.getMaxAge(), cookie.getSecure());
}
//of course, we really need to modify ServerCookie
//but this is the general idea
if (HTTPOnly) {
sb.append("; HttpOnly");
}

//if we reached here, no exception, cookie is valid
// the header name is Set-Cookie for both "old" and v.1 ( RFC2109 )
// RFC2965 is not supported by browsers and the Servlet spec
// asks for 2109.
addHeader("Set-Cookie", sb.toString());

cookies.add(cookie);
}

Any feedback is appreciated.

PS: For more on HTTPOnly and how it can be a part of your defense-in-depth web application security strategy, see http://msdn2.microsoft.com/en-us/library/ms533046.aspx

6 comments:

Arshan said...

Thanks a lot, Jason.

Anyways, I love this. Doing, not ranting. This is what the Interwebs should be about.

If you modified the appendCookieValue() instead, do you think Tomcat would commit the patch?

Or do you think because the J2EE specification is silent on HTTPOnly that they'll reject it (assuming it actually is silent- haven't checked)?

Either way- add this patch to JBoss too, and who knows how many vulnerabilities you could personally prevent from occurring.

Jim Manico said...

Thank you for your kind words, Arshan. You hit the nail on the head - the ServerCookie class needs a serious change, the appendCookieValue function being a major part of the that.

The issue is not the patch itself; but some of the Tomcat core developers (Remy and others) think the concept of HttpOnly is just a "Microsoft Hack." We shall see.

I'll gladly take this patch to JBoss next. Less ranting, more doing! :)

Arshan Dabirsiaghi said...

Of course it's a hack - but it's hack that's been standardized.

I hope they change their minds!

Jim Manico said...

I completed the needed patches for Tomcat HttpOnly and submitted for review from the core dev team. See https://issues.apache.org/bugzilla/show_bug.cgi?id=44382

Mark said...

Did you ever get any response from JBoss on including this in JBoss Web?

Jim Manico said...

JBoss is one of the last on my list - I never heard back from them.

Websphere and Weblogic both support httponly session cookies, thou.