Cross site request forgery

Cross-Site Request Forgery (CSRF)

Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated. CSRF attacks specifically target state-changing requests, not theft of data, since the attacker has no way to see the response to the forged request. With a little help of social engineering (such as sending a link via email or chat), an attacker may trick the users of a web application into executing actions of the attacker’s choosing. If the victim is a normal user, a successful CSRF attack can force the user to perform state changing requests like transferring funds, changing their email address, and so forth. If the victim is an administrative account, CSRF can compromise the entire web application. (from www.owasp.org)

CSRF in Asp.net MVC

Luckily Asp.Net MVC has a build in mechanisme to fight those attacks. In the previous versions of Asp.Net MVC you used an AntiForgeryToken. You needed to put a ValidateAntiForgeryToken attribute on your MVC action or controller. In the view, you needed to instruct RAZOR to create an AntiForgeryToken. This will give the visitor a cookie called __RequestVerificationToken. This cookie will have the same value as a hidden input field, called __RequestVerificationToken, generated by the Html.AntiForgeryToken() method. This method needed to be placed inside a form tag or the using of a Html.BeginForm().

   public class MyController : Controller
    {
    [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Create(SomeModel model)
        {
          ...
        }
    }
   @using(Html.BeginForm())
   {
    @Html.AntiForgeryToken()
   }

And in Asp.net MVC 6?

In the Asp.net MVC 6 the mechanisme has changed a bit. You still need to put the ValidateAntiForgeryToken attribute on your MVC action, but if you use the build in form taghelper, the forgerytoken will by default be created and placed within the form tag.

   public class MyController : Controller
    {
    [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Create(SomeModel model)
        {
          ...
        }
    }
   <form asp-action="Create">

   </form>

This will result in the following html.

<form action="/My/Create/" method="post">

<input name="__RequestVerificationToken" type="hidden" value="CfDJ8DCDWZ4iOzZDmNKl5HFAUd2qQe4qwOhVP4znwDlTDINNK_h-1a2v0A1aDPCdb4lEgc9X_cTsjKkCDUCYh9EKr7HqXI3hvIRfnRItwfJwbImCZIx38uDfwVu5jzdVZOcaXUUmoPBDtG6-0__0FVezb-U" />
</form>

If you don’t want the forgerytoken to be created you can pass a false value to the form taghelper for the antiforgery parameter.

   <form asp-action="Create" asp-antiforgery="false>

   </form>
  1. Have you noticed any issues with the AntiForgeryToken not matching when the form can be cached via the cache tag helper?

    • It doesn’t work well together and you will get errors, which, in my opinion, are a good thing. If you think about it, if you’re in a data-entry app, do you want to cache your data-entry forms? Probably not.

Leave a Reply to Greg Cancel Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>