MVC anti-forgery token

1.9k views Asked by At

I've got a public MVC 5 web-site, using the anti-forgery token. Every day a large number of errors are logged in the form of "The anti-forgery cookie token and form field token do not match.", and a lesser number in the form of "The required anti-forgery cookie "__RequestVerificationToken" is not present.".

The problem is not reproducible, it occurs for different people on different pages at different times. Closing the browser resolves the problem - sometimes just using the Back button and re-trying resolves the problem.

  • As the website works for the vast majority of users, I can rule out missing ValidateAntiForgeryToken attributes in controllers, likewise, I can rule out missing or duplicate @Html.AntiForgeryToken() code in the views.

  • The website runs on a single server, so I can rule out different machinekeys in the web.config (I've tried running the website with and without this setting anyway).

  • The application pool is set to restart each night, and there's plenty of spare resource on the server, so I can rule out the application pool restarting and invalidating sessions (especially as this isn't logged in the event log or anywhere else).

  • I've hit the problem very rarely - I definitely have cookies enabled, so I can rule out cookies being disabled. I can also rule out javascript being disabled, as user's can only progress so far into the site without JS - and errors occur on pages beyond this point.

  • I've disabled all caching, setting nocache, nostore etc. This seemed to reduce the occurrence of the issue, but it still persisted (I had to re-enable caching for a variety other reasons).

What other options are there to consider?

I am so frustrated by this I am considering turning off anti-forgery protection and contributing to the global weakening of security.

1

There are 1 answers

1
Kadir On

Make sure you have AntiForgery attributes both in controller and forms.

If you are doing ajax post maybe you can send RequestValidationToken as a parameter.

$('input[name=__RequestVerificationToken]').val()

Also maybe somebody attacking your site or using some bots to get content or post forms.