Safe ASP.Net MVC application against cross site attacks - 2

Session Hijacking:
ASP.Net identifies users by session ID cookie which called ASP.Net_SessionId by default, and if we use Forms Authentication, then a second cookie is used called .ASPXAUTH. If an attacker can obtain these cookies, then they can include them in a request to our server and impersonate one of our users. The browser by default preventing the javascript from a site to access cookies of another site. But if the attacker has been able to inject a script into one of our pages, then the browser believes that the script is part of our application and grands access to the session cookies.

We can protect our site by keeping a record of each client IP address when a session starts, we can deny any requests that originate from a different IP. But you should avoid this technique when you deal with the public internet.

We can mark a cookie with the HttpOnly flag, and the browser will hide its existence from javascript but will continue to send it via all HTTP requests. By default ASP.Net marks ASP.Net_SessionId and .ASPXAUTH as HttpOnly. Of course you can apply HttpOnly to your session cookies when you create them.

Cross-Site Request Forgery (CSRF):
Unfortunately, anyone can mount a devastating attack by enticing our users to visit an HTML page which is hosted in external domain. When the exploit page loads, it simply sends a valid form submissions to our post-handling action method. The exploit can easily hide its actions, for example by submitting the POST request using Ajax.

There are two main strategies to defend against CSRF attacks:
  1. Validate the incoming HTTP Referrer header: If we check it and find it referencing an unexpected third-party domain, we know that it's a cross site attack.
  2. Require some user-specific token to be included in sensitive requests.
A better option is to have our server generate a secrete user-specific token, put it in hidden field and then check that the token is present and correct when the form is submitted. Fortunately, MVC Framework has a ready made implementation for this technique.

You can detect and  deny CSRF attacks by combining Html.AntiForgeryToken() helper and its ValidateAntiForgeryToken filter that decorate the target action method. Html.AntiForgeryToken() will render a hidden field with name  __RequestVerificationToken and in the same time it will give the user a cookie whose name begins with __RequestVerificationToken. This cookie will contain the same random value as the corresponding hidden field. This value remains constant throughout the the visitor's browsing session. We must validate incoming form submissions by decorating the target action method with ValidateAntiForgeryToken attribute. If the values of incoming hidden field does not match the value of the cookie, The MVC Framework will throw an exception and block the request.

The MVC anti-forgery system has the following features too:
  • The cookie name has a suffix that varies according to the name of your application's virtual directory.
  • Html.AntiForgeyToken() accepts optional path and domain parameters that controls which URLs are allowed to see the cookie.
  • The  __RequestVerificationToken hidden field value will also contain  the user name of logged user obtained from HttpContext.User.Identity.Name (if user logged in).  ValidateAntiForgeryToken attribute will match the random value and also will match the logged user name.
The MVC anti-forgery system has a few limitation:
  • Legitimate users' browsers must accept cookies, or ValidateAntiForgeryToken attribute always throw an exception an block the request.
  • It works only with forms submitted as POST requests not GET requests. That should not cause any problem because GET request must not change any data, just read.
  • If you have any weak point in your application, XSS attackers can use it to get the random token generated by Html.AntiForgeyToken().

Build your MVC application securely:
  1. Don't write any public method inside a controller class that will not be an action method. By default any public method is an action method, other methods should be wrote in model section. If you have to write a method that will not be an action, make sure it will be private or make it public but you must decorate it with NonAction attribute.
  2. Prevent  Model Binding to change sensitive data by using Bind attribute to set up white/black list that restrict which properties model binding is allowed/not allowed to populate.
1 2

Comments

Popular posts from this blog

Android : How to change progress bar color at runtime programmatically?

ASP.Net MVC : Conditional Validation using ValidationAttribute

How to fire RowCommand event of nested GridView?