This post has been republished via RSS; it originally appeared at: IIS Support Blog articles.
Anti-forgery token is used to prevent CSRF (Cross-Site Request Forgery) attacks. Here is how it works in high-level:
- IIS server associates this token with current user’s identity before sending it to the client
- In the next client request, the server expects to see this token
- 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:
Error messages clearly state the root causes but the solution is not always straightforward. I will try to provide possible solutions in the post.
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:
After decoding: 01-1A-CF-C9-ED-F1-3E-1E-7D-C9-9E-BE-90-2E-22-91-36-01
- Form token:
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).
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.
In my case, the clients were using the application in a way that is not supposed to be used. For example:
- User goes to the login page
- User opens a second tab in the same browser and goes to the login page
- User logins in the first tab (or the second, the order doesn’t matter)
- 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:
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:
Add “heuristic checks” to the Application_Start method of Global.asax file: