The MVC platform: the new anti forgery token

Today we’re going to talk about a new feature introduced by the RC version of ASP.NET AJAX: the anti forgery token. The idea is render a hidden token which is validated during post back, ensuring that your app is protected against cross-site request forgery. Using this feature in your apps is as simple as calling the Html.AntiForgeryToken from within your form and adding the ValidateAntiForgeryTokenAttribute to the action method you want to protect.

Using it is simple, but what happens behind the scenes? That’s what we’re going to see right away.

Unlike what you might expect, the AntiForgeryToken method is really an instance method of the HtmlHelper class. Currently, you have 2 overloads: one without parameters and another with a single parameter that lets you pass a String with the salt that should be used in the creation of the token (more about that in the next paragraphs).

Internally, this methods performs some interesting operations:

  • it starts by getting the “HTTP only” cookie which is used for keeping an anti forgery token created internally. If it finds an existing anti forgery cookie in the cookie collection available from the current request, it will deserialize its  value. If there isn’t any cookie, a new one will be created and initialized with random new anti forgery token.
  • The token obtained is used to create a new anti forgery token which ends up being persisted in a hidden field of the form.

Now, we need to understand how this token is verified during a post back. As you might suspect, the ValidateAntiForgeryTokenAttribute performs an important role in this verification. By now, you shouldn’t be surprised to know that the ValidateAntiForgeryTokenAttribute is a filter which also implements the IAuthorizationFilter. When its OnAuthorization method is called, it starts by recovering the previously created cookie and recovers its value (as you recall from the previous paragraphs,the cookie value should be generated during the initial rendering of the form and is only a random anti forgery token).

After getting that value,the attribute tries to recover the serialized value of the token that has been injected in the view through a form’s hidden field. It will then compare both deserialized values and see if they’re equal. If they are, then it will perform one last check: compare the salt on the token and see if it matches the initial salt that was passed when you called one of the overloads of the Html.AntiForgeryToken.

As you’ve probably guessed, if any of these checks fails you’ll end up with a HttpAntiFogeryException which ends the current request processing (in this case, eventual exception filters will get a crack at handling the current exception).

Until now, I’ve been talking a lot about anti forgery tokens, but I still haven’t mentioned the class that is responsible for representing that concept. It’s time to say hi to the… yep, you’ve guessed it: the AntiForgeryToken class! This is a really simple class which exposes only three properties: Salt, Value and CreationDate. Of them, you’ll only able to set the salt (that is, that’s the only property you can influence when you use the helper method). Internally, it uses the RNGCryptoServiceProvider class for generating a random number that guarantees the uniqueness of the token.

And we’re missing only one thing to tie up the anti forgery history: the serialization process. Along the post, I’ve mentioned serialization several times. That job is performed by the AntiForgeryTokenSerializer class which is where all the “cool tricks” are. If you look at the code, you’ll end up seeing that serialization is performed through a singleton instance of the TokenPersister type, which inherits from the PageStatePersister class. The class has to create a dummy page in order to get a valid state formatter which is used for serializing the cookie and hidden field’s values.

And that’s it. Easy, right? Keep tuned for more on the internals of the MVC framework.


~ by Luis Abreu on February 9, 2009.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: