Reputation: 3266
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:
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
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
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