Skip to content

Securing Your Cookies: HTTPOnly Flag for Cookie Theft Defense

Securing Your Cookies: HTTPOnly Flag for Cookie Theft Defense

Missing HttpOnly flags on cookies are a common finding in Web Application penetration testing. Many times, there is confusion surrounding whether it is necessary to enable this flag though. However, cookies can contain session tokens and other values that can be useful to a malicious actor and should be protected. If the cookies do not need to interact with JavaScript or other scripting languages it is best to set this flag to “true”, so a malicious actor is not able to steal the values present in the cookie.

According to OWASP (Open Web Application Security Project ), “The HttpOnly cookie attribute instructs web browsers not to allow scripts (e.g. JavaScript or VBscript) the ability to access the cookies via the DOM document.cookie object.”[1] Even though the HttpOnly cookie flag is not new, many times it is found to be absent during penetration tests.

A cookie is used by developers to hold data, one very important piece of data is a session cookie. Session cookies represent the user and need to be protected in order to assure that a malicious actor cannot use the cookie to impersonate the user. In this situation, the HttpOnly flag should be set. Some cookies do need to interact with JavaScript based on their function, setting the HttpOnly flag, in this case, would render the cookie useless to the application.

In order to demonstrate how the HttpOnly flag works two files were created. An HTML file, welcome.html consisting of a form and a PHP file, cookieWelcome.php that echoes user input from the form and contains two cookies.

The code for welcome.html can be found below:

<html>
<body>
<form action=”cookieWelcome.php” method=”post”>
Name: <input type=”text” name=”name” size=”50″ ><br>
E-mail: <input type=”text” name=”email” size=”50″ ><br>
<input type=”submit”>
</form>
</body>
</html>

Below is the code for cookieWelcome.php:

<html>
<body><?php
setcookie(“sessionId”,”261957163849573″, time() + (86400 * 30), “/”, null, null, true);
setcookie(“Missing_HttpOnly”,”482749185763514″, time() + (86400 * 30), “/”, null, null, false);
?>Welcome <?php echo $_POST[“name”]; ?><br>
Your email address is: <?php echo $_POST[“email”];?>
</body>
</html>

In PHP, a cookie is set with the following values:

setcookie($name, $value, $expirationTime, $path, $domain, $secure, $HttpOnly);

Cookie “sessionId” has the HttpOnly flag set.

setcookie(“sessionId”,”261957163849573″, time() + (86400 * 30), “/”, null, null, true);

XSS (Cross-Site Scripting) can be used to access cookie information. There are three types of XSS, reflected, stored and DOM-based. In this example, reflected XSS where the result is returned to the user and the payload is not stored is used to demonstrate the values returned with and without the HttpOnly flag. First, test if the application is vulnerable to XSS. We need the application to run our JavaScript code in order to access the cookies associated with the application.

Use the following values as input in the form:

Name:

<script>alert(“XSS Vulnerable”)</script>

The script was successfully run in the application.

Next, we will attempt to determine which cookies are available using JavaScript. Document.cookie is used to retrieve the value of cookies.

Use the following input:

Name: Daisy
Email:

<script>alert(document.cookie)</script>

An alert box exposing the value of Missing_HttpOnly is returned. An attacker could use this cookie to impersonate a user.

<$XSS_RISK>

XSS enables an attacker to steal sensitive information like cookie values. While this example uses reflected XSS if the XSS was stored any visitor to the application could potentially have cookies, session tokens, or other private information compromised.

The browser’s developer tools can also be used to examine cookies. A checkmark is present in the HttpOnly column for sessionId, validating the use of HttpOnly. Since HttpOnly was used sessionId was not returned by the JavaScript code.

In conclusion, HttpOnly is necessary when the values contained in a sensitive cookie need to remain confidential.

References:

[1] https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html