Rob Gray
Rob Gray

Reputation: 3266

RequestVerificationToken cookie not present in Response

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.

Upvotes: 2

Views: 4975

Answers (2)

Philipp P
Philipp P

Reputation: 619

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);
}

Upvotes: 2

Josh
Josh

Reputation: 16532

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.

Upvotes: 6

Related Questions