Friday, December 19, 2008

Helping Protect Cookies with HTTPOnly Flag

Submitted by Ryan Barnett 12/19/2008

If you are unfamiliar with what the HTTPOnly cookie flag is or why your web apps should use it, please refer to the following resources -

The bottom line is this - while this cookie option flag does absolutely nothing to prevent XSS attacks, it does significanly help to prevent the #1 XSS attack goal which is stealing SessionIDs. While HTTPOnly is not a "silver bullet" by any means, the potential ROI of implement it is quite large. Notice I said "potential" as in order to provide the intended protections, two key players have to work together -

  • Web Applications - whose job it is to append the "HTTPOnly" flag onto all Set-Cookie response headers for SessionIDs, and
  • Web Browsers - whose job it is to identify and enforce the security restrictions on the cookie data so that javascript can not access the contents.

The current challenges to realizing the security benefit of the HTTPOnly flag is that universal adoption in both web apps and browsers is still not there yet. For example, depending on your web app platform, you may not have an easy mechanism to implementing this feature. For example - in Java you could following the example provided here on the OWASP site -, however this doesn't work well for the JSESSIONID as it is added by the framework. Jim Manico has been fighting the good fight to try and get Apache Tomcat developers to implement his patch to add in HTTPOnly support - The point is that with so many different web app development platforms, it isn't going to be easy to find support for this within every web app that you have to secure...

As for browsers - they too have sporadic, non-consistent adoption of HTTPOnly. It was for this reason that the OWASP Intrinsic Security group has started an RFC Spec for HTTPOnly - Hopefully this group will get some traction with the various browser developers.

So, at this point you might be asking yourself - Ryan, that is interesting news and all, but what can a web application firewall do to help with this issue? I would then in turn reply - Great question, I am glad that you asked. ;)

One of my pet peevs with the web application security space is the stigma that is associated with a WAF. Most everyone only focuses in on the negative security and blocking of attacks aspects of the typical WAF deployment and they fail to realize that WAFs are a highly specialized tool for HTTP. Depending on your circumstances, you may not ever intend to do blocking. There are many other use-cases for WAFs and how they can help, in this case as a tactical response tool to help address an underlying vulnerability In this case, we could monitor when back-end/protected web applications are handing out SessionIDs that are missing the HTTPOnly flag. This could raise an alert that would notify the proper personnel that they should see if editing the web language code is possible to add this feature in. A rule to do this with ModSecurity would look like this -

# Identifies SessiondIDs without HTTPOnly flag
SecRule RESPONSE_HEADERS:/Set-Cookie2?/ "!(?i:\;? ?httponly;?)" "chain,phase:3,t:none,pass,log,auditlog,msg:'AppDefect: Missing HttpOnly Cookie Flag.'"
SecRule MATCHED_VAR "(?i:(j?sessionid(php)?sessid(aspjservjw)?session[-_]?(id)?cf(idtoken)sid))" "t:none"

While this rule is pretty useful for identifying and alerting of the issue, many organizations would like to take the next step and try and fix the issue. If the web application does not have a way to add in the HTTPOnly cookie flag option internally, you can actually leverage ModSecurity+Apache for this purpose. ModSecurity has the ability to set environmental data that Apache reads/acts upon. In this case, we can modify our previous rule slightly to use the "setenv" action and then we add an additional Apache "header" directive that will actually overwrite the data with new Set-Cookie data that includes the HTTPOnly flag -

# Identifies SessiondIDs without HTTPOnly flag and sets the "http_cookie" ENV
# Token for Apache to read
SecRule RESPONSE_HEADERS:/Set-Cookie2?/ "!(?i:\;? ?httponly;?)" "chain,phase:3,t:none,pass,nolog"
SecRule MATCHED_VAR "(?i:(j?sessionid(php)?sessid(aspjservjw)?session[-_]?(id)?cf(idtoken)sid))" "t:none,setenv:http_cookie=%{matched_var}"

# Now we use the Apache Header directive to set the new data
Header set Set-Cookie "%{http_cookie}e; HTTPOnly" env=http_cookie

The end result of this ruleset is that ModSecurity+Apache can transparently add on the HTTPOnly cookie flag on the fly to any Set-Cookie data that you define. Thanks goes to Brian Rectanus from Breach for working with me to get the Header directive syntax correct.

Hopefully the data presented here will help people who would like to have the security benefit of this flag however are running into challenges with implementing it within the app.

No comments: