Recently I came across a client request that related to his web-site being a soft target for XSS attacks and the client was completely devastated by the frequency of the site being hijacked and brought down so much so that he decided to give up on the ASP.NET framework development having (mis)heard that it is more prone to being attacked due to the vulnerabilities in the framework.
I beg to differ.
The ASP.NET framework is not only the most robust of a lot but also gives the developers incredible tools and techniques to not just avert specialized XSS/CSRF attacks but also DOS and DDOS attacks targetting web-farms/web-gardens.
Fact of the matter is, that it is not the framework but bad programming and not enough knowledge with the right tools and techniques to leverage in order to to tackle CSRF and XSS attacks that is to be blamed.
I here by explain the solution I implemented which not only helped the client re-instate his faith in Microsoft in general but also keep a close watch on the code being written and getting it frequently audited for security vulnerabilities by specialists with the domain of web-site security.
CSRF (cross-site request forgery, a.k.a. Session riding) is an attack which forces an end user to execute unwanted actions on a web application in which he/she is currently authenticated. With a little help of social engineering (like sending a link via email/chat), an attacker may force the users of a web application to execute actions of the attacker's choosing. A successful CSRF exploit can compromise end user data and operation in case of normal user. If the targeted end user is the administrator account, this can compromise the entire web application.
This attack exploits the vulnerability that happens because web browsers use the user’s authentication info (user's session cookie, basic auth. credentials, IP address, Windows domain credentials, etc.) automatically for all future requests once the user has been authenticated. The site is unable to distinguish between requests originating from user actions on the site and those originating from the malicious link which the user clicked while his session cookie is valid.
The way the malicious link is constructed is explained here. Another paper describes how an e-mail with a malicious IMG tag was sent to victims. By viewing the email message, the user initiated an HTTP request, which sent a router command to change the DNS entry of a leading Mexican bank, making any subsequent access by a user to the bank go through the attacker's server.
A more detailed description of how this attack can happen in ASP.NET MVC applications is described here.
Official Solution: AntiForgery Token Helper:
ASP.NET MVC provides the API AntiForgeryToken to solve this issue. 
This is based on the solution to put a user-specific token as a hidden field on legitimate forms, thus preventing malicious forms or links to simulate a valid form post because they cannot possibly know this token.
To implement it in your MVC application you need to follow these steps:
1. Add the call to AntiForgeryToken() html extension in your form:
This will generate a cookie name __RequestVerificationToken on the visitor’s computer with the same random value in the hidden field above.
You can pass a parameter (named the “salt”) to the call to Html.AntiForgeryToken() that will be used to avoid having the same token across all parts of the application, in case the attacker manages to know the token value in a part of the application.
2. Filter the action method with the ValidateAntiForgeryToken attribute:
Adding the salt it would be like:
This approach is limited to sites that use webforms and not REST services that use JSON requests. For the case where an ajax call is placed in a form it can be done using a javascript function that assigns the __RequestVerificationToken value before submitting the post request, as described here. The problem really happens when there is no interface developed for the site (i.e. REST services, a.k.a. JSON-based payloads).
Adjustment for JSON calls in MVC sites:
Two approaches exist for JSON-only inputs:
1. Since [ValidateAntiForgeryToken] only works with form-based payloads, it will raise an exception for JSON-based payloads. Sergey Barsky’s article describes how he implemented his own attribute to overcome this problem and he named it [MyValidateAntiForgeryToken]. It is simply an overload of the original attribute that takes into account the case when the content type is JSON and retrieves the variable with the standard name (__RequestVerificationToken) from the cookies collection and validates it against a value with the same name coming from the JSON object itself. The default behavior does the same algorithm except that it compares the value coming from the HTML hidden field with the value coming from the cookies. The last part of this article describes how he added this value to the knockout view model. This is specific to his case but in general you would design your JSON request to include a field with the name (__RequestVerificationToken).
2. Another approach described by Justin Etheredge here. Instead of putting the verification token as a variable inside the JSON payload like the approach above, Justin decided to inject the token inside the AJAX headers. He uses the JQuery feature called prefilters, where a prefilter is a callback function that is called before each request is sent, and prior to any $.ajax() option handling. This is the syntax:
He first creates an overload of the standard html extension @Html.AntiForgeryToken() and names it @Html.AjaxAntiForgeryToken().
Then this is how he injects the token using the prefilter feature:
He uses the method setRequestHeader of the jqXHR object, described here. jqXHR is a superset of the XMLHttpRequest object that results from an ajax call which provides more control and gives more info than the standard object.
Finally he also overloads the standard attribute [ValidateAntiForgeryToken] by changing only one line from:
Now you are using the JQuery environment itself to make sure the token is appended to the call.
Conclusion
This article described what a CSRF attack is and how it is prevented in an ASP.NET MVC application that has forms, and also various options for writing custom code that to make sure it is validated against for the case of a JSON payload that does not depend on forms.









 
No comments:
Post a Comment