2

My ASP.NET MVC application prevents CSRF attacks by using the ValidateAntiForgeryToken attribute and calling Html.AntiForgeryToken to write a hidden input element with the token value, and also place the token in the cookie.

My exception log is reporting occurences of HttpAntiForgeryException that look like they were triggered from valid Requests (the Referrer looks correct). The Response causing the exception also contains __RequestValidationToken in the Form field, with the token value. However, the necessary cookie is missing from the Request, causing the Validation to fail and exception to be thrown.

I'm trying to think of why this cookie is missing and have come up with the following possible reasons:

  1. Cookies collection is full for the domain. - If this were the case here I'd expect to see 20/50 cookies in each request (BTW all the User-Agents are IE7 and IE8) and somehow the cookie is being dropped. I'm seeing between 3 and 23 cookies in various occurences of the exception
  2. Data limit of cookies has been reached. - This isn't happening. By looking at the logs I can see the cookie collection is small.
  3. The response is being sent back before the cookie can be added. - Not sure about this one. Manually calling Reponse.Flush in the head results in an Exception stating the cookies collection can't be modified after the repsonse has been sent.
  4. ?

In desparation I turn to the people at SO and ask for any other possible causes of this missing cookie that I can investigate.

Rob Gray
  • 3,186
  • 4
  • 33
  • 34
  • 3
    I am seeing the exact same issue. It only happens in IE and there are other cookies present. I have even seen this error when the cookie is present. It has been plaguing me for some time now and I fear I will have to remove my antiforgery protection. – Josh Apr 06 '11 at 20:53
  • 1
    Ever find the source of this issue? – Ted Dec 15 '12 at 20:37
  • Is it possible that the user disabled cookies on the browser? – stepanian Jan 21 '10 at 06:48
  • Each exception log entry has other cookies in each Request. – Rob Gray Jan 21 '10 at 06:51

2 Answers2

6

I was having the exact same issue. My content was being presented through a cross domain iframe. According to Adam Young, IE will automatically block third party cookies unless you define a P3P policy in the header.

I added code to inject the p3p policy into the header and just call it from each action that I use in my iframe. So far, we have not seen this error turn up. I hope this solution helps someone else.

public static void SetP3PCompactPolicy()
{
    HttpContext.Current.Response.AddHeader("p3p", 
    "CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"");
}

I also defined a machine key, although I'm not sure that was necessary.

Josh
  • 16,286
  • 25
  • 113
  • 158
2

According to Josh's answer (crossdomain-issue within an iFrame), I placed the piece of code into the BeginExecute-method of my controller to achieve the desired behaviour for each call. In addition with a base-controller, every other controller is derived from, you can achieve that all your actions will run if your site is embedded within an iFrame.

protected override IAsyncResult BeginExecute(System.Web.Routing.RequestContext requestContext, AsyncCallback callback, object state)
{
    requestContext.HttpContext.Response.AddHeader("p3p", "CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"");

    return base.BeginExecute(requestContext, callback, state);
}
Philipp P
  • 609
  • 1
  • 9
  • 12