Anti-forgery token and anti-forgery cookie related issues
Published Nov 05 2019 11:09 AM 99.7K Views
Microsoft

Anti-forgery token is used to prevent CSRF (Cross-Site Request Forgery) attacks. Here is how it works in high-level:

  1. IIS server associates this token with current user’s identity before sending it to the client
  2. In the next client request, the server expects to see this token
  3. If the token is missing or it is different, then the server rejects the request (Reference)

 

These are some of the anti-forgery token related error messages you may see in Event Viewer:

 

The provided anti-forgery token was meant for a different claims-based user than the current user.

The provided anti-forgery token was meant for user “”, but the current user is “X”.

The anti-forgery cookie token and form field token do not match.

The required anti-forgery cookie “__RequestVerificationToken” is not present.

 

A sample stack trace:

 

 

at System.Web.Helpers.AntiXsrf.TokenValidator.ValidateTokens(HttpContextBase httpContext, IIdentity identity, AntiForgeryToken sessionToken, AntiForgeryToken fieldToken)at System.Web.Helpers.AntiXsrf.AntiForgeryWorker.Validate(HttpContextBase httpContext)at System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor)

 

 

clipboard_image_0.jpeg

 

Error messages clearly state the root causes but the solution is not always straightforward. I will try to provide possible solutions in the post.

 

Root Cause

 

Long story short: For anti-forgery validation to pass, the security token of the session token must be equal to the security token of the field token.

 

I saw different names for these cookies in different sources. They can be used interchangeably:

 

Session token = Cookie token
Field token = Form token
Security token = anti-XSRF Token

 

Longer story: For validation to pass, form token and session token are correlated (Important: This is not comparison for equivalence. You can’t correlate them by simply comparing them in Fiddler). There is anti-XSRF token inside each of those. The anti-XSRF token is the one that should match precisely. Reference

 

For the example:

  • Cookie/Session token:
    Aq81hoVCPIpq3Q6xjBi0EFKKwSFwnKROgS7tyXF393eAN8rdMNZwkVkEgjQokKviKLVST1iWdgDxBt-g3FIughAsczUO7tyWhtz3fs88xMM1
    After decoding: 01-1A-CF-C9-ED-F1-3E-1E-7D-C9-9E-BE-90-2E-22-91-36-01
  • Form token:
    i411mJIr0mZKrk17g4Hf-0_G6aXOJLkzzGfd5yn2mVsTqj-35j_n0YUUCzFRXoFet3BXUVpBicpL3p-AqPPA3XEXEtykt4X-_MbRIxLQH6M1
    After decoding: 01-1A-CF-C9-ED-F1-3E-1E-7D-C9-9E-BE-90-2E-22-91-36-00-00-00-00

As you see above, the raw tokens are different but extracted anti-XSRF tokens are the same so the validation passes. (There are additional bytes at the end. They are flags. The username was going to be encoded there if it was an authenticated user).

 

Solution

 

A possible solution to anti-forgery related errors depends on the way how the issue occurs. I would recommend trying to find out the user behavior that causes these errors.

 
User behavior

In my case, the clients were using the application in a way that is not supposed to be used. For example:

  1. User goes to the login page
  2. User opens a second tab in the same browser and goes to the login page
  3. User logins in the first tab (or the  second, the order doesn’t matter)
  4. User attempts to login in the remaining login tab

Informing your users about the points below can significantly reduce the number of anti-forgery errors:

  • Using the application only in one tab
  • Not using the Back button to go back to the login page
  • Using “Log out” button once they are done with the application
  • There might be other related scenarios. I would recommend contacting your users and asking what action they took to generate the issue

 

Catch the Exception

Catching the anti-forgery exceptions in your code and redirecting user to the homepage if they are already authenticated should prevent most of the errors. Here is a sample code block:

 

 

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
...
}
 
protected override void OnException(ExceptionContext filterContext)
{
    base.OnException(filterContext);
 
    var action = filterContext.RequestContext.RouteData.Values["action"] as string;
    var controller = filterContext.RequestContext.RouteData.Values["controller"] as string;
 
    if ((filterContext.Exception is HttpAntiForgeryException) &&
        action == "Login" &&
        controller == "MyController" &&
        filterContext.RequestContext.HttpContext.User != null &&
        filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated)
    {
        filterContext.ExceptionHandled = true;
 
        // redirect/show error/whatever?
        filterContext.Result = new RedirectResult("/homepage");
    }
}

 

It may take time to fine tune this code block. There is no one solution that fits all.

 

Remove the anti-forgery validation from the login page

I saw customers not using the anti-forgery validation in the public pages such as login, about, register pages. Anti-forgery token’s main purpose is to prevent attacker using authentication cookie for doing things on behalf of the actual user. Since the user isn’t authenticated yet in the login page, there are customers removing the validation.

 

Try quick fixes

The common “possible solutions” to anti-forgery token/cookie related issues are disabling output caching and enabling heuristic checks. I will include the code snippets here.

Disable output caching:

 

[OutputCache(NoStore = true, Location = System.Web.UI.OutputCacheLocation.None)]

 

 

Add “heuristic checks” to the Application_Start method of Global.asax file:

 

AntiForgeryConfig.SuppressIdentityHeuristicChecks = true;

 

6 Comments
Co-Authors
Version history
Last update:
‎Apr 13 2021 12:03 PM
Updated by: