3

According to MDN document:

To prevent cross-site scripting (XSS) attacks, HttpOnly cookies are inaccessible to JavaScript's Document.cookie API; they are only sent to the server.

I found a scenario to replace HttpOnly cookie by JavaScript, here's the PoC in ASP.NET:

<%@Page Language="C#" %>
<script runat="server">
void Page_Load(object sender, EventArgs e) 
{
    if (Request["m"] == "check") 
    {
        Response.Write("Cookie=" + Request.Cookies["C"].Value);
        Response.End();
    }
    else 
    {
        Response.AppendCookie(new HttpCookie("C") 
        {
            Value = "ByServer",
            HttpOnly = true
        });
    }
}
</script>
<html>
<body>
    <div>
        document.cookie -&gt; <span id=t></span>
    </div>
    <script>
        document.getElementById("t").innerHTML = document.cookie;
        document.cookie="C=ByClient";
    </script>
    <a href="?m=check">Check Cookie</a>
</body>
</html>

In the test of Chrome, reading document.cookie gets nothing proves that the HttpOnly cookie is indeed unreadable to JavaScript. But by setting document.cookie = "C=ByClient", two cookies with different paths exist concurrently.

enter image description here

Then check the cookie from server side, Request.Cookies["C"] returns "ByClient" given by JavaScript, but not "ByServer" assigned by server. The HttpOnly cookie is overwriten by client.

The result will be different if we set the exact HttpCookie.Path:

    Response.AppendCookie(new HttpCookie("C") 
    {
        Value = "ByServer",
        HttpOnly = true,
        Path = "/asp/httponlycookie"
    });

Now document.cookie="ByClient" failed to add or change the cookie, the HttpOnly cookie is protected.

enter image descriptiont here

Can I reach a conclusion: that HttpOnly property only guarantees the cookie not readable to JavaScript, the HttpOnly cookie is still possible to be replaced or overwriten by JavaScript?

Darkthread
  • 4,109
  • 5
  • 33
  • 137
  • _"The HttpOnly cookie is changed by client."_ No, it's not. You seem to have added an extra cookie with the same name. – Cerbrus Oct 04 '18 at 13:27
  • @Cerbrus thanks for the link, it cleared up my confusion. – Darkthread Oct 05 '18 at 00:21
  • 1
    To me this indicates that you can "shadow" an HttpOnly cookie in JavaScript by setting it to a different value on a different path, which may allow you to alter the value of the HttpOnly cookie in requests made to the server. So, I don't think this question is a duplicate. – Elliott Beach Jun 15 '19 at 20:18
  • The __Host- prefix was created to prevent these kinds of security problems because a cookie with a __Host- prefix can only be set with 1) the secure flag, 2) path=/, and 3) domain left unset, meaning that another cookie with the same name cannot be set with a different signature. Therefore this effectively prevents JavaScript from setting a cookie with the same name as an HttpOnly cookie. And it prevents man in the middle attacks since the connection must be secure. – PHP Guru Sep 30 '20 at 04:04

0 Answers0