Published: 17 Dec 2010
By: Xianzhong Zhu

Since ASP.NET MVC 1, CSRF (Cross Site Request Forgery) has been considered by introducing a set of anti-forgery helpers. In this article, we are to detail into CSRF related concepts and ASP.NET MVC's helper functions again CSRF.

Contents [hide]

The Experience ASP.NET MVC 3 Beta series

  • Part 1 In the coming ASP.NET MVC 3.0 a lot of new good things will be added or enhanced. In this article, we are going to focus upon the new view engine Razor to see how it will simplify the view design.
  • Part 2 In addition to the introduction of a new view engine Razor, ASP.NET MVC 3 Beta has also introduced numerous new HtmlHelpers, such as Chart, Crypto, WebGrid, WebImage, WebMail, etc. This article aims to introduce the two commonly-used new helper controls – WebGrid and Chart using relevant examples.
  • Part 3 In this installment, I'll first tell you a short story about unobtrusive JavaScript. Then, we'll delve into the unobtrusive client-side validation support. Finally, we will research into a more interesting story - the unobtrusive jQuery-Based Ajax support.
  • Part 4 In this article, we are going to continue to explore the other three important helpers - WebImage, WebMail, and Crypto.
  • Part 5 Starting from this article, let's explore some more advanced concepts and related utilizations associated with flexible Dependency Injection support introduced in ASP.NET MVC 3 Beta.
  • Part 6 In the last article, we've mainly discussed the new-styled DI support in ASP.NET MVC 3 Beta/RC in relation to the two new services - IControllerActivator and IViewPageActivator. Obviously, both of them are connected with controllers and views. In this article, however, we will shift our attention to the Model (generally called viewmodal in many blogs) related DI manipulations.
  • Part 7 Since ASP.NET MVC 1, CSRF (Cross Site Request Forgery) has been considered by introducing a set of anti-forgery helpers. In this article, we are to detail into CSRF related concepts and ASP.NET MVC's helper functions again CSRF.
  • Part 8 In this series of articles, we are going to explore as many as possible aspects of cache programming in the latest ASP.NET MVC 3 RC2 framework. And also, all the related samples have been tested against the latest ASP.NET MVC 3 RC 2.
  • Part 9 In the first part of this series, we've mainly explored Output Cache related issues. In this second part, however, we are going to delve into the general Data Cache topic.
  • Introduction

    Network security becomes one of the first issues to consider in modern Web development. In general, the most common types of Web attacks from the point view of software include Cross-site Scripting (XSS), SQL Injection, Session hijacking, Cross-site Request Forgery (CSRF), and Hidden field tampering. Compared with the other web attacks, CSRF attacks are probably the least well known, so that they are easier to exploit, with extreme and increasing danger.

    The good news is, since ASP.NET MVC 1, CSRF has been considered by introducing a set of anti-forgery helpers. In this article, we are to detail into CSRF related concepts and ASP.NET MVC's helper functions again CSRF.

    NOTE

    The test environments we'll utilize in the sample application are:

    1. Windows XP Professional (SP3);

    2. .NET 4.0;

    3. Visual Studio 2010;

    4. ASP.NET MVC 3 RC (http://www.microsoft.com/downloads/en/details.aspx?FamilyID=a920ccee-1397-4feb-824a-2dfefee47d54);

    What’s Cross-Site Request Forgery (CSRF)

    In the industry, alongside XSS (Cross Site Scripting) and SQL Injection, Cross-site Request Forgery (CSRF) attacks represent the three most common and dangerous vulnerabilities to common web applications today. CSRF attacks are probably the least well known yet relatively easy to exploit.

    According to wikipedia's definition, cross-site request forgery, "CSRF" in short, is a confused deputy attack against a Web browser. The attack works by including a link or script in a page that accesses a site to which the user is known (or is supposed) to have been authenticated. As long as the attacker uses some tricks, such as by e-mail or chat software to send the link, the attacker will be able to force a Web application user to perform the selection operation of the attacker.

    The following characteristics are common to CSRF:

    • Involve sites that rely on a user's identity
    • Exploit the site's trust in that identity
    • Trick the user's browser into sending HTTP requests to a target site
    • Involve HTTP requests that have side effects

    By the way, CSRF is also called "one-click attack" by Dino Esposito in his article at MSDN, where he brought us a vivid picture to illustrate what CSRF was. For brevity, we are to omit the detailed description.

    Ways to stop CSRF

    On the whole, there are three widely-used techniques for defending against CSRF attacks, as enumerated below.

    • Use a user-specific token
    • Validate the HTTP Referer header
    • Set a custom header via XMLHttpRequest

    This first way may be the most popular approach to defense CSRF. In detail, put a user-specific token as a hidden field in legitimate forms (often use some random value, such as a GUID, stored in the visitor's Session collection or into a Cookie), and validate that the received token is correctly bound to the user's session.

    This second is the simplest way to defense CSRF. In detail, make the server side accept requests only from trusted sources. There is an obvious deficiency associated with this technique – the server has to deal with requests lacking a Referer header entirely. Thus, sites can either process these requests or block them. If a site processes requests that lack a Referer header, the solution may be dangerous because the Referer header can be suppressed by an attacker. On the other hand, if the site refuses to process these requests, an appreciable part of users will be excluded.

    The last action against CSRF is related to XMLHttpRequest. Ajax's popularity has increased recently with more sites implementing AJAX interfaces. Sites can defend against CSRF by setting a custom header via XMLHttpRequest and validating that the header is present before processing state-modifying requests. Although effective, this defense requires sites to make all state-modifying requests via XMLHttpRequest, a requirement that prevents many natural site designs. Although this article is not going to explore the AJAX related CSRF issue, DiXin did give you a good solution in this aspect, to be mention later on.

    NOTE

    According to the HTTP RFC #2616 Section 9.1.1 Safe Methods, GET should not have the significance of taking an action. They shouldn't be allowing GET requests to take actions.

    Cross-site Request Forgery Attack Samples

    In Phil Haack’s blog, he presented us a detailed yet simple banking sample to illustrate how the hacker performed the CSRF attack upon a common banking account if the web system didn't take anti-forgery actions. For brevity, I'm not going to give such similar samples but leave space to the real topic – ASP.NET MVC's anti-forgery solution.

    ASP.NET MVC’s Solution to Prevent CSRF

    To defense the CSRF attach, ASP.NET MVC has introduced a group of anti-forgery methods since version 1.0. In detail, they are:

    • AntiForgeryToken: a public method of the HtmlHelper class.
    • AntiForgeryData: an internal class containing the anti-forgery related data.
    • AntiForgeryDataSerializer: an internal tool class, which is used to encode/decode the AntiForgeryData structure mainly through the Base64 coding and decoding algorithms.
    • The ValidateAntiForgeryToken attribute: when some special actions in the controller are decorated with this attribute an anti-forgery related validation will be performed.

    In fact, ASP.NET MVC right takes the first technique described above– create a user-specific token, to try to avoid CSRF.

    Easily seen, the key lies in the HTML Helper method AntiForgeryToken. When we call @Html.AntiForgeryToken() (in this case we use the new Razor syntax) in a form on our view page we will obtain a hidden input and a Cookie with a random string assigned. The Html.AntiForgeryToken method will create a cookie on the client-side machine and adds a hidden field (to be detailed later).

    And then, on our target action method in the controller we need to add the [ValidateAntiForgeryToken] attribute, which will handle the verification that the correct token was supplied.

    In detail, to protect a particular HTML form, we just need to include the method invocation to Html.AntiForgeryToken() inside the form, like this:

    In this way, Html.AntiForgeryToken() will give the visitor a cookie called __RequestVerificationToken_Lw__, with the same value as the random hidden value implies above.

    To gain more details, let's use the above anti-forgery helpers to build up a concrete sample application.

    Put the AntiForgery Helpers into action

    1. Create Model

    Now, let's first define a simple model named CustomerViewModel, as follows.

    2. Create anti-forgery required action

    Now, let's create a pair of actions both named Login. Obviously, the first one is used to trigger the related view page Login.cshtml; the second one will be used to deal with the POST request sent out from the view page.

    The first point to notice is in the second method we've decorated it with the [HttpPost] attribute, which will cut off all possible requests made through a plain GET. In fact, as stressed previously, this is a MUST HAVE to mitigate CSRF attacks.

    Next, to validate an incoming form post, we have to add the [ValidateAntiForgeryToken] filter to the second action method. If the validation passes (and no CSRF attack takes place), we navigate the use to the Index view page related to the Home controller – just for test's aim; or else, an error info will be returned.

    In other words, ValidateAntiForgeryToken instructs the invoker of the ASP.NET MVC method to look for some special content in the request body before executing the code.

    More specifically, the ValidateAntiForgeryToken attribute contains code that kicks in during the authorization phase of an action method request, ensuring the posted request contains a cookie and a form field with a common fixed name. If any of these items are missing, an exception is thrown; otherwise, the attribute ensures that the content of the cookie and the input field match.

    Next, let's construct the test view page.

    3. Create View to protect CSRF

    Now, right click the above first action Login to create a strong-typed view page named Login.cshtml. The related contents are given below.

    The first point to notice is we've called the HTML Helper method AntiForgeryToken inside the <form/> block. This will create a hidden <input/> element and a related cookie on the user's machine.

    Another point to notice is if there is only the attribute ValidateAntiForgeryToken specified in the action but not the corresponding HTML helper Html.AntiForgeryToken invocation in the above view page, then there will be a related HttpAntiForgeryException exception thrown out at the running time, with the message being "A required anti-forgery token was not supplied or was invalid".

    4. Watch the running-time client-side source code

    To make a contrast, let's first comment out the above two anti-forgery related operations to see what will happen at the running time. Listing 5 shows the related main source code (using the url "http://localhost:2047/customer/login"). For brevity, I've slightly edited it.

    There is nothing peculiar here, just with ordinary HTML code.

    Next, let's get rid of the above comments and run the sample again. This time, you will find the related source code like that in Listing 6.

    Obviously, with the above change, a hidden <input/> element named __RequestVerificationToken is inserted into the form, with its value being the anti-forgery used token. At the same time, there is also a cookie named __RequestVerificationToken_Lw__ is generated with the same value as the hidden <input/> element. When the above form is submitted, they are both sent to server. This is all added by ASP.NET MVC framework to defend CSRF attacks.

    In fact, we can also set a breakpoint at the second action Login to find out what really takes place in the behind scene. Figure 1 below illustrates the snapshot of the debug Watch window.

    Figure 1: Track the cookie related stuffs during the course of debugging

    Track the cookie related stuffs during the course of debugging

    As you've seen, the above snapshot shows the incoming request contains a cookie called __RequestVerificationToken_Lw__. And further, if you enter Request.Cookies[0] in the Watch window, you can look more closely at the cookie value and other related data.

    On the other hand, on the client side, after submitting the form you can open up Firebug (we select Firefox 3.5 to run the sample application) to track the Request header structure. In this way, you will also catch sight of a cookie named __RequestVerificationToken_Lw__ that matches the previous one captured from the action method Login. Figure 2 illustrates the related snapshot in Firebug.

    Figure 2: Track the anti-forgery related cookie from the client-side Firebug tool

    Track the anti-forgery related cookie from the client-side Firebug tool

    If the server side action verifies via the authorization filter [ValidateAntiForgeryToken] that the incoming request has a Request.Form entry called __RequestVerificationToken and the request comes with a cookie of the corresponding name and their random values match, then the above submission and request will go through as normal. But if not, there will be an authorization failure with message "A required anti-forgery token was not supplied or was invalid". This prevents CSRF because even if a potential victim has a __RequestVerificationToken_Lw__ cookie, an attacker can't find out its value, so they can't forge a valid form post with the same value in the request.

    Hence, there will be no trouble for the legitimate users to submit the form with the introduction of this anti-forgery action in ASP.NET MVC.

    In fact, as hinted previously, if you remove the invocation to the HTML helper method AntiForgeryToken in the view page and run the sample again, you will surely meet an exception as shown in Figure 3 below.

    Figure 3: A related exception will be thrown if conditions are not met

    A related exception will be thrown if conditions are not met

    NOTE

    Although since ASP.NET MVC 1 the anti-forgery helpers have been introduced, there are some slight differences between the implementations of MVC 2/3 and MVC 1. For instance, ASP.NET MVC 2/3 adopted a newer data format to store the anti-forgery token. Therefore, if you deploy your upgraded application while visitors are actively using your site, their __RequestValidationToken_Lw__ cookies will suddenly become invalid, leading to HttpAntiForgeryException errors. Visitors won't be able to continue using your site until they clear their session cookies by closing and reopening their browsers. Therefore, for small applications, you can manually edit your global error handler page to display a related modesty and prominent message saying this. For larger Internet applications, though, this way may not be acceptable – you'd better think of a general solution for this awkwardness.

    In the next section, we will continue with the anti-forgery related topic – salt.

    Salt related story

    Till now, we've only used the simplest form of the HtmlHelper method AntiForgeryToken. There are, in fact, still several forms of overrides for it (obtained via .NET Reflector):

    First, the third form is the most common implementation compared with the preceding two. Second, the first one does not use a salt value. Slight different from the term "salt" in cryptology, salt here represents just an arbitrary string. A different salt value means a different anti-forgery token will be generated. So, even if an invader manages to get hold of a valid token somehow, he can't reuse it in other parts of the application where a different salt value is required. As you've guessed, for best security, we must keep the salt value secret.

    As indicated before, all the three method will generate a hidden form field (anti-forgery token) that is validated when the form is submitted. Especially, in the third form the field value is generated using the specified salt value, domain, and path.

    To use salt is simple. In the action method, you can write your action like this:

    And in the view page, you can call the helper method like this:

    In real scenarios, however, things are not as simple as told above. For example, one Web product might be deployed in many web servers. If a constant salt is evaluated in compile time, after the product is built and deployed to many clients, they all have the same salt. This will cause the clients' dislike and in some degree result in insecurity. I.e. these scenarios require generating salt at the runtime. To work around this, DiXin gave a better solution. And also, you will find in this great blog an Ajax related anti-forgery solution mentioned also in the previous section.

    Can ASP.NET MVC prevent against all CSRF attacks?

    The user-specific token policy can work well in blocking CSRF. However, there are still a few limitations we should be aware of:

    • Legitimate users' browsers must open up Cookies; or else, the attribute [ValidateAntiForgeryToken] will always deny their form posts.
    • It works only with forms submitted as POST requests, not as GET requests. This isn't much of a problem if you follow the HTTP guidelines, which say that GET requests should be read-only.
    • It's easily bypassed if you have any XSS vulnerabilities. Any such hole might provide a chance for an attacker to read any given victim's current __RequestVerificationToken value, and then use it to forge a valid posting. Basically, if you have XSS, your CSRF-protection is a waste of time, so ensure you are not vulnerable to either.

    Anti CRSF Tokens help prevent fishing attacks. However, they aren't meant to prevent spammers or web scrapers from running automated scripts against your web application. Again, bear in mind, that if your site suffers from other XSS vulnerabilities (where the privacy of your cookies or sessions are compromised) then Anti CRSF Tokens don't work at all.

    The last thing to watch out for is around Flash and Silverlight. Both of these technologies do not subscribe to the same origin policy. Instead, they both use cross domain policy files to restrict access to remote resources. In another word, Flash/Silverlight script can only access resources on your site if you publish a cross domain policy xml file on your own site. If you do publish this file, you have to ensure allowing a white list of trusted third-party servers and never allow all.

    Summary

    In this article, we first introduced the Cross-site request forgery (CSRF) attack related concepts and corresponding actions to defense it. Then, we explored the ASP.NET MVC provided actions in beating CSRF through a detailed example. In fact, this article can only serve as an introductory story concerning CSRF attack. As you've seen, the CSRF attack is the result of how browsers handle cookies and cross domain form posts and is not specific to any one web platform. So, many web platforms may include their own mitigations to the problem.

    The Experience ASP.NET MVC 3 Beta series

  • Part 1 In the coming ASP.NET MVC 3.0 a lot of new good things will be added or enhanced. In this article, we are going to focus upon the new view engine Razor to see how it will simplify the view design.
  • Part 2 In addition to the introduction of a new view engine Razor, ASP.NET MVC 3 Beta has also introduced numerous new HtmlHelpers, such as Chart, Crypto, WebGrid, WebImage, WebMail, etc. This article aims to introduce the two commonly-used new helper controls – WebGrid and Chart using relevant examples.
  • Part 3 In this installment, I'll first tell you a short story about unobtrusive JavaScript. Then, we'll delve into the unobtrusive client-side validation support. Finally, we will research into a more interesting story - the unobtrusive jQuery-Based Ajax support.
  • Part 4 In this article, we are going to continue to explore the other three important helpers - WebImage, WebMail, and Crypto.
  • Part 5 Starting from this article, let's explore some more advanced concepts and related utilizations associated with flexible Dependency Injection support introduced in ASP.NET MVC 3 Beta.
  • Part 6 In the last article, we've mainly discussed the new-styled DI support in ASP.NET MVC 3 Beta/RC in relation to the two new services - IControllerActivator and IViewPageActivator. Obviously, both of them are connected with controllers and views. In this article, however, we will shift our attention to the Model (generally called viewmodal in many blogs) related DI manipulations.
  • Part 7 Since ASP.NET MVC 1, CSRF (Cross Site Request Forgery) has been considered by introducing a set of anti-forgery helpers. In this article, we are to detail into CSRF related concepts and ASP.NET MVC's helper functions again CSRF.
  • Part 8 In this series of articles, we are going to explore as many as possible aspects of cache programming in the latest ASP.NET MVC 3 RC2 framework. And also, all the related samples have been tested against the latest ASP.NET MVC 3 RC 2.
  • Part 9 In the first part of this series, we've mainly explored Output Cache related issues. In this second part, however, we are going to delve into the general Data Cache topic.
  • <<  Previous Article Continue reading and see our next or previous articles Next Article >>

    About Xianzhong Zhu

    I'm a college teacher and also a freelance developer and writer from WeiFang China, with more than fourteen years of experience in design, and development of various kinds of products and applications on Windows platform. My expertise is in Visual C++/Basic/C#, SQL Server 2000/2005/2008, PHP+MyS...

    This author has published 81 articles on DotNetSlackers. View other articles or the complete profile here.

    Other articles in this category


    Code First Approach using Entity Framework 4.1, Inversion of Control, Unity Framework, Repository and Unit of Work Patterns, and MVC3 Razor View
    A detailed introduction about the code first approach using Entity Framework 4.1, Inversion of Contr...
    Exception Handling and .Net (A practical approach)
    Error Handling has always been crucial for an application in a number of ways. It may affect the exe...
    jQuery Mobile ListView
    In this article, we're going to look at what JQuery Mobile uses to represent lists, and how capable ...
    Book Review: SignalR: Real-time Application Development
    A book review of SignalR by Simone.
    JQuery Mobile Widgets Overview
    An overview of widgets in jQuery Mobile.

    You might also be interested in the following related blog posts


    You should NOT use ASP.NET MVC if. . . read more
    New class: ASP.NET MVC Boot Camp developer training read more
    Six New Videos on ASP.NET Dynamic Data read more
    Will ASP.NET MVC be the main web UI platform for ASP.NET? read more
    The Wait is Over: ASP.NET 3.5 Extensions Preview Posted read more
    Joel Spolsky: Indigo won't enable a new class of applications read more
    Top
     
     
     

    Please login to rate or to leave a comment.