Thursday, March 7, 2013

AntiForgeryToken in MVC


Security in any application is as important as the UI of the application, we can compromise with the UI but we cannot do the same with Security as it possess a great risk to the data we use inside the application. The common security breach can come in the form of Cross Site Request Forgery or CSRF hack. CSRF is the lesser known cousin of XSS.  It is different from another script hacking called as Cross Site scripting XSS.

What is Cross Site Scripting?
XSS is one of the most common application-layer web attacks. XSS commonly targets scripts embedded in a page which are executed on the client-side (in user’s web browser) rather than on the server-side. The concept of XSS is to manipulate client-side scripts of a web application to execute in the manner desired by the malicious user. Such a manipulation can embed a script in a page which can be executed every time the page is loaded, or whenever an associated event is performed.

What is Cross Site Request Forgery?
Cross Site Request forgery also called One Click Attack or Session Riding is a type of a hack where the some unwanted and unauthorized command given by a hacker from a user which is trusted by the web site is executed on server and exploits the trust. It first came in light early at 2001. 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

How does it work?

Here the hacker inserts some script or link in the code within the browser where the user is using its application or an authenticated one. For example a banking user presented with a link which is redirect the user to some other website with some link rather than the actual bank site. In this way, the attacker can make the victim perform actions that they didn't intend to, such as logout, purchase item, change account information, retrieve account information, or any other function provided by the vulnerable website.

Let’s take a sample MVC web site the site properly blocks anonymous users from taking any action. You can see that in the code for the controller:



[Authorize]
public class HomeController : Controller
{
  //...ur code
}
Here we use the AuthorizeAttribute on the controller (without specifying any roles) to specify that all actions of this controller require the user to be authentication.


The hackers create the page same as our own page and put some Java script on the page load itself so that the value of the page can be submitted to some false address. The Hacker can create a page like.

<html>
<head>
    <title></title>
</head>
<body>
    <form name="badform" method="post"
     action="http://localhost:4129/Home/Transfer">
        <input type="hidden" name="FinalAccountId" value="2" />
        <input type="hidden" name="amount" value="1000" />
    </form>
    <script type="text/javascript">
        document.fakeform.submit();
    </script>
</body>
</html>

The hacker created an HTML page that replicates the fields in bank transfer form as hidden inputs and then runs some JavaScript to submit the form. The form has its action set to post to the bank’s URL.

When the user lands in this page which looks exactly the same as the original one, When the unsuspecting bank user visited the hackers website, it recreated a form post to transfer funds, and the browser unwittingly sent the still active session cookie containing the user’s authentication information to the hackers site thus the page will be executed and we will lost our information.


Prevention in MVC

The first step to avoid this is to add the ValidateAntiForgeryTokenAttribute to the action method. This will validate the “token” value created at the time of session start and will be different for each session for each browser.

[ValidateAntiForgeryToken]
public ActionResult Transfer(int destinationAccountId, double amount) {
  ///... Ur code
}

The same we need to add in our View as well, for example a method Html.AntiForgeryToken() 



<% using (Html.BeginForm("Transfer", "Home")) { %>
<p>
    <label for="Amount">Amount:</legend>
    <%= Html.TextBox("Amount")%>
</p>
<p>
    <label for="destinationAccountId">
      Destination Account:
    </legend>
    <%= Html.DropDownList("destinationAccountId", "Select an Account") %>
</p>
<p>
    <%= Html.AntiForgeryToken() %>
    <input type="submit" value="transfer" />
</p>
<% } %>


By adding this the page will get loaded with some encrypted token value which we can see by view source as for example

<input name="__RequestVerificationToken" 
  type="hidden" 
  value="WaE634+3jjeuJFgcVB7FMKNzOxKrPq/WwQmU7iqD7PxyTtf8H8M3hre+VUZY1Hxf" />


This is the most common way  to prevent Cross-Site Request Forgery (CSRF) attacks is to append unpredictable challenge tokens to each request and associate them with the user’s session. Such tokens should at a minimum be unique per user session, but can also be unique per request. By including a challenge token with each request, the developer can ensure that the request is valid and not coming from another source other than the user. This token value cannot be predicted so it will make each request a unique one.





Token In Ajax Call

The same prevention we can add in the Ajax call as well so that the threat can be minimize we can verify the token in the Ajax call by using the jQuery cookie plugin to replace getCookie:

var csrftoken = $.cookie('csrftoken');


Hopefully you have like this post and will try to implement the same in all your important development. Please do share your valuable comment on the same article.

Thanks
Anil Kumar Pandey
Microsoft MVP, Microsoft MCC, DNS MVM

Kontera