Preventing CSRF Attacks in ASP.NET Core 2.0

Problem

How to prevent Cross Site Request Forgery attacks in ASP.NET Core.

Solution

Create an empty project and update Startup to add middleware and services for MVC:

Create a model and service:

Note: the implementation of the service doesn’t matter here but can be getting data from EF etc. In the sample I just stored data in-memory.

Add a controller:

Add an Index view:

Add a Create view:

Run and Browse to Create view and observe it’s source:

Also note the cookie added for anti-forgery:

Add a new entry and observe the request in fiddler:

Discussion

OWASP 2013 classifies Cross Site Request Forgery (CSRF) as one of the Top 10 risk and is present if attacker can force victims browser to send forged request to your web application and it considers it a legitimate request.

ASP.NET Core provides an easy to use mechanism to prevent such attacks by:

  1. Creating a cookie with an encrypted token.
  2. Emitting a hidden form element (__RequestVerificationToken) with an encrypted token.

The cookie and form field will be sent to server on subsequent requests, as observed in the above fiddler screenshot. Server will reject the request if any of the two (cookie or form field) is missing e.g. excluding the form field returns a 400 (Bad Request):

Server will also throw an exception if any of the two (cookie or form field) is modified e.g. below I changed the value of form field:

How does it work

In order to add the hidden tokens we just need to use the form tag and apply [ValidateAntiForgeryToken] attribute on our controller action. Yes that’s it.

You could also apply [AutoValidateAntiforgeryToken] attribute on your controller to enable forgery token validation for all the unsafe actions (e.g. POST and PUT) on your controller:

If you want to apply validation for all the controllers in your application, you could add a global filter when configuring MVC services:

With validation enabled globally, you could disable for certain actions using the [IgnoreAntiForgeryToken] attribute:

This last option is the safest option and would be my preference i.e. apply validation globally and ignore as needed.

Note: without the token validation attribute or filter, hidden tokens inside the form and cookie are not going to stop the CSRF attacks.

Source Code

GitHub: https://github.com/TahirNaushad/Fiver.Security.Csrf

Leave a Reply