CSRF in MVC asp.net

Sometime 140 characters is not enough to explain your point. Recently on twitter Troy Hunt [someone you should be following] said the following in response to my claim that asp.net mvc did not offer out of the box protection from CSRF.

Before I go any further let me define IMO the characteristics a good CSRF prevention system should have:

  • Should prevent CSRF in ideal conditions (you and your users never ever get pwned)
  • Should not require tokens to remain secret forever
  • Should be on by default for all unsafe requests (see 9.1.1 of the http spec)

When attempting to prevent a CSRF attack on a website using asp.net MVC, and asp.net webforms. The developer is responsible for adding the following to their forms <%= Html.AntiForgeryToken() %> and actions which should be protected must be tagged with the [ValidateAntiForgeryToken] attribute.  This system is built on an opt in approach. By default all actions on all controls do NOT protect against CSRF. Further more because it is a direct reuse of the webforms code base it only works for form submissions. Which is great if that is all one does. However, in the last several years of development I have used less and less forms, and more and more json based services. For the sake of argument lets say you did follow the Microsoft line, and only ever use form submissions, and never forgot to tag your actions, then you are safe right? Nope, because the tokens are generated are essentially an hmac of the current user’s username they are not in anyway tied to the user’s current session. This means that even if the user logs out there CSRF tokens from the previous session are usable by an attacker.  It does not matter what you do as a user, you can change your password, log in log out clear your browser cache, none of this will invalidate any previously stolen CSRF token. This leads to the undesirable characteristic of once compromised always compromised.  Yes, you are safe. Troy hunt pointed out to me the implementations in webforms and mvc are different. MVC’s implementation of CSRF tokens (at least in the latest version) does not suffer from the same weakness as webforms which did not invalidate the tokens between sessions.

So of the three characteristics of a good CSRF prevention system asp.net’s system only has the first one has the first and second; It prevents CSRF in ideal conditions.  Sooner or later a CSRF token will be compromised because a user logs in from a public computer, gets a virus, is the victim of a main in the middle attack, or the site has an XSS vulnerability. This is not a question of if only a question of when.

The third characteristic (secure by default) is achievable in Microsoft’s ecosystem through the use of a custom filter that automatically requires CSRF protection on all unsafe methods similar to this: https://gist.github.com/jmaxxz/3190357


Previous Post