Why It Is Important to use Anti-Forgery Tokens in ASP.NET Web Forms

Adam Murchison, 15 November 2017

When creating a webform it is highly important to have anti-forgery tokens generated for the user at the correct stage. It is equally important to know when to validate these anti-forgery tokens. The validation of the token allows the site to trust the users input. This blog will delve into why it is so important to have anti-forgery tokens, and when to validate them.

Why is it important to implement anti-forgery tokens?

This is important because without this implementation Cross-Site Request Forgery (CSRF) can be exploited by hackers. This is done by the site trusting a given users requests (without an anti-forgery token) and the hacker tricks a user to clicking on a malicious link that takes them to a form that submits a post request to the server with the user’s authentication. The HTML.AntiForgeryToken() on the html webform generates a token on the webform (not the hackers malicious form) that is submitted and validated on a post request with the [ValidateAntiForgeryToken] filter within the corresponding controller. This is a very high level overview of how CSRF works which the below image shows, if this sparks your interest I will be writing a blog in the near future on CSRF.

image

How are the tokens generated by HTML.AntiForgeryToken() used?

The token generated by HTML.AntiForgeryToken() which should be called in the webform html contents, is referred to as the form token. Another HTTP-only token is generated at the same time the form token is, this token is used to validate the form token by the server. The form token is unique to the user logged in, which means multiple users can be logged in and the server will know which tokens to authenticate for each user. The form token is refreshed every time that the form is submitted and validated (via POST req and [ValidateAntiForgeryToken] filter), thus resulting in a different form token. If the token was not refreshed every time the token is validated it would lead to the token being the same for every form. This would be a massive security flaw, as once a hacker has the token of one of the forms they could submit data sent by other forms to do malicious things. Wait… How would the hacker gain access to one of these tokens you ask? This would be done by a hacker reading the page contents which can be done in multiple ways e.g. Man in the Middle attack, DNS poison etc.

image

When should I use the ValidateAntiForgeryToken filter?

You only use this filter on a POST request, it is not used in GET request because a GET request does not manipulate data. GET requests should be a read-only operation. All POST requests should use the ValidateAntiForgeryToken for the most secure web forms.