Mitigating cookies theft using HttpOnly

Cross Side Scripting (XSS)

Cross Side Scripting is a technique that enables attackers to inject client-side script into Web pages viewed by other users. It's a computer security vulnerability typically found in Web applications. This means that a hacker would be able to insert JavaScript in a text field, say a blog post. This script would be executed by the browser, through this page, for every user that reads the post thread after it is published. The script could in turn read the current users cookie and send it to a a remote service and store is for later use.

To protect a cookie against the XSS vulnerability there is a header flag available for the “Set-Cookie” HTTP response header. This header will mitigate the risk of client side script accessing the protected cookie (if the browser supports it).

Testing the theory

To test this theory, I will demonstrate it using a test application. Our test application consists of a ASP.Net web application and some javascript. The following paragraphs explain the code in detail.

Javascript

Our test javascript will retrieve the cookie collection from the response , find our specific cookie and post the value in a paragraph.

The code blow shows our simple code that just reads the cookies from the response and displays it in a paragraph.

  1:     <script type="text/javascript">
  2: 
  3:         function getCookie(c_name) {
  4:             var i, x, y, ARRcookies = document.cookie.split(";");
  5:             for (i = 0; i < ARRcookies.length; i++) {
  6:                 x = ARRcookies[i].substr(0, ARRcookies[i].indexOf("="));
  7:                 y = ARRcookies[i].substr(ARRcookies[i].indexOf("=") + 1);
  8:                 x = x.replace(/^\s+|\s+$/g, "");
  9:                 if (x == c_name) {
 10:                     return unescape(y);
 11:                 }
 12:             }
 13:         }
 14: 
 15:         function setCookieValue(c_name) {
 16:             var username = getCookie("testcookie");
 17:             if (username != null && username != "") {
 18:                 document.getElementById('pCookieValue').innerHTML = username;
 19:             }
 20:             else {
 21:                 document.getElementById('pCookieValue').innerHTML = "Cookie not found in request";
 22:                 }
 23:             }
 24:     
 25:     </script>

ASP.Net application

Besides the JavaScript, the ASP.Net page contains the required HTML to display the cookie value.

The code in the ASPX page, used to display the cookie value is displayed below.

  1: <body onload="javascript:setCookieValue('testcookie');">
  2:     <form id="form1" runat="server">
  3:     <div>
  4:         <asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
  5:         <p id="pCookieValue"></p>
  6:     </div>
  7:     </form>
  8: </body>

Code behind

The code behind contains the code to set the cookie value. I use IsPostBack so we see the difference between the initial request and the refresh.

  1: protected void Page_Load(object sender, EventArgs e)
  2: {
  3:     if (IsPostBack)
  4:     {
  5:         var c = Response.Cookies["testcookie"];
  6:         c.Value = "Testcookie Value";
  7:     }
  8: }

Now is we open the page in our browser we get the following response.

CookieNotFound

Remember this is the expected response, because we did not set the cookie yet. We will set it in the PostBack logic.

So, after we click the “Button” button the cookie is added to the request and the value dispayed on the screen

SetCookieNoHttpOnly

CookieFound

Addind the HttpOnly

Now we add the security code to make the cookie HttpOnly.
See the OWASP resource link below for more ways to set this flag, and also in other programming languages.

  1: protected void Page_Load(object sender, EventArgs e)
  2: {
  3:     if (IsPostBack)
  4:     {
  5:         var c = Response.Cookies["testcookie"];
  6:         c.Value = "Testcookie Value";
  7:         c.HttpOnly = true;
  8:     }
  9: }

Now when we open the page, and click the “Button” button, the cookie is set again using the HttpOnly flag. But this time the value is not displayed on the screen.

SetCookieHttpOnly

CookieNotFound

Conclusion

So, to conclude our findings. The HttpOnly flag is applied to prevent a user from accessing the cookie using client side script. A sidenote, although obvious: Keep in mind that some cookie are actually used to pass state information between requests and probably need to be accessed client side.

NOTE: Just to clearify, this does not mean that XSS is also prevented, these two are related but not the same.

Resources

The Open Web Application Security Project (OWASP)
HTTP Cookies
Cross-site scripting

Comments

Popular posts from this blog

Yet Another WiX Tutorial Part 3: Customizing the UI dialogs

Encrypted Cookies using ASP.NET

Yet Another WiX Tutorial Part 2: Your First Installer