Security Feature in ASP.Net MVC

Today I would like to say something about security features in MVC. This article is intended for both those with a basic idea of MVC as well as the experienced ones.

Agenda

  1. Cross Site Scripting (XSS).
  2. Cross site request forgery (CSRF).
  3. Authentication.
    1. Windows
    2. Forms

Security, the name itself speaks a lot. It is required everywhere to safeguard your personal belongings, our information, and so on. It is quite simple to add physical security when you say providing security at your home, at banks, at the office. But when it comes to online, I mean a web then it's quite difficult to manage since a website is hosted in a server and it is available or can be accessed from everyone's home/office and so on.

Security

Talking about each of the threats and the ways for avoiding it.

Cross Site Scripting (XSS)

XSS is a kind of attack, wherein any malicious user tries to inject scripts in input fields like a TextBox or a textarea. This attack can affect my site by executing some unwanted scripts. So we need to take care and avoid this kind of script injection. This attack is most common, so Microsoft had a built-in functionality of handling these scripts in HTML input tags.

Cross Side Scripting

Let’s consider a sample wherein I will use 2 TextBoxes and try inputting some script tags as data.

detail form

Once I click on Ok, the SaveData Actionmethod will be triggered. This method returns an aspx view.

  1. public ActionResult Savedata(Customer c)  
  2. {  
  3.    //Save logic  
  4.    return View("SavedataAspx",c);  
  5. }  
When I tried inputting this <b> tag, I got the following error. That says someone is trying to insert the dangerous script. This threat is handled easily by the .Net Framework.

server error

But think of a case where I want to enter this kind of information in my TextBox like styling the data. The best example is C-SharpCorner.com or CodeProject.com. I mean I want to allow this script tag to be entered but as a data and not as an executable code.

In this case I need to say, don’t validate these tags and print it after encoding. This can be done by setting the attribute for ActionMethod.
  1. [ValidateInput(false)]
  2. public ActionResult Savedata(Customer c)  
  3. {  
  4.    return View("SavedataAspx",c);  
  5. }  
Note: This setting can be done at the global level also, in other words at webconfig.
  1. <httpRuntime requestValidationMode="2.0"/>  
After setting this attribute, I don’t get an error, instead it tries to execute the script or render the tags entered into TextBox. This is true only if my view is .aspx.

save data

Output:
user detail

To print the text as it is, then I need to use the Server.HtmlEncode() method as in the following:
  1. <%=Server.HtmlEncode(Model.CustomerAddr) %>  
Output:
Output

But if we return a Razor View Engine then this is automatically encoded by Html helper methods for the input type.

 input type

Html helper

Output:
back

Note: This signifies that when we use Razor syntax (Razor Engine), Cross Site Scripting attack is prevented as it encodes the data as a default behavior. But with Aspx engine, Cross Site  Scripting is possible as a default behavior.
 
In case you want to execute the script in Razor then you can use @Html.Raw(Model.CustomerAddr).
 
Cross Site Request Forgery (CSRF) Attack

Now the second important threat in the web application is a Cross Site Request Forgery (CSRF) Attack.

CSRF attack

This is the most common attack we find today. You may have seen an ad that appears suddenly on some of the websites. Once we click on that popup ad, it redirects to some URL and moves back to our own website. We think that it is just an ad popup. But you have a wrong impression. Actually these redirects try to hack our data or insert some invalid data in our website. This is what we call Cross Site Request Forgery where we are redirect to other websites without our knowledge and hacked our data.

CSRF attack

I will like to show you a small demo of how forgery occurs. 
  1. Run the current application http://localhost:44247/Home/Index.

  2. Right-click on the webpage and open view source.

    view source

    It will look something like this.

  3. Copy only the form tag section and paste it in a new HTML page. Note: This HTML page is not needed to be in a same project. It can be an altogether different application. Remove all the unwanted attributes and tags and keep only the input type controls and the action should be the full URL : http://localhost:44247/Home/SaveData as shown below:
    1. <form action=" http://localhost:44247/Home/SaveData" method="post" style=”display:none;”><input name="CustomerId" type="text" value="1000" /> <br />   
    2.     <input id="CustomerName" name="CustomerName" type="text" value="HACK" /> <br />   
    3.     <textarea cols="20" id="CustomerAddr" name="CustomerAddr" rows="2">  
    4.     HACK   
    5.     </textarea>   
    6. </form>  
    Add a small JavaScript code :
    1. <script type="text/javascript">  
    2. function fnCall() {  
    3.    window.setTimeout(function(){ window.document.getElementById("btnok").click();   
    4.    }, 2000);  
    5. }  
    6. window.onload = fnCall();  
    7. </script>  
  4. Now set your own random text in a TextBox. Just to hide the form from others set the style to display:none. and keeping the text as loading... Save the HTML file with any name like Ad.html.

  5. Run the HTML page.

    Now since we have specified the post method to our original website, it will redirect to our website and will execute the SaveData actionmethod. We will get the output as:

    detail

    Now I was able to access your website and post some malicious data. Think of the situation where you have been saving the logic written in this actionmethod and it contains one field that accepts an Amount. This is called a Cross Site Request Forgery Attack.

    This attack can be avoided in MVC using a token called AntiForgeryToken.

    When posting the data to the server, keep a token key along with data that will always validate on the server. This is done in MVC following 2 simple steps.

    1. Add a Htmlhelper method @Html.AntiForgeryToken() within the form tag. This will generate a Token key on the View.

      code

    2. Add an Attribute ValidateAntiForgeryToken on the Savedata ActionMethod. This will validate the key passed in the post.
      1. [ValidateInput(false)]  
      2. [ValidateAntiForgeryToken]  
      3. public ActionResult Savedata(Customer c)  
      4. {  
      5.    // return View("SavedataAspx",c);  
      6.    return View("Savedata", c);  
      7. }  
      That’s it. See the following code, how the token key looks as in.

      html code

      Now if we try to run the same html file in other words- Ad.html, then we will get an error:

      Ad html
      I hope you got it.


Authentication
 
The third thing that we normally require in our website is Authentication.

Authentication
Authentication in MVC is similar to ASP.Net Authentication but the syntax differs. In Authentication, there are various ways, let’s talk about each one of them. For showcasing Authentication, I am not using already available classes that come in selecting the project template. I am manually creating the procedure.
  1. Windows Authentication

    organization

    This mainly is used for Intranet applications.

    The following is the procedure to enable Windows authentication:

    1. Go to the webconfig file, set the authentication tag with the mode set to Windows.
      1. <system.web>  
      2.    <authentication mode="Windows"></authentication>  
      3. </system.web>  
    2. By default, Windows Authentication is set to Disabled. Go to the properties of the project and enable Windows Authentication.

      Windows Authentication

    3. This will enable your Windows authentication, so when you try to access any ActionMethod from URL, you will be shown a credentials window as shown below:

      ActionMethod

      Enter your Windows credentials and everything works for you.

  2. Forms Authentication

    Now let’s talk about Forms Authentication. This is mainly used for Internet applications. Use the following procedure:
    1. Set the authentication mode in webconfig. Also set the default login URL. This URL will be your controller/ActionMethod name.
      1. <system.web>  
      2.    <authentication mode="Forms">  
      3.       <forms loginUrl="Account/Index" timeout="2000"></forms>  
      4.    </authentication>  
      5. </system.web>  
    2. Create a model class LoginDetail.
      1. public class LoginDetail  
      2. {  
      3.    Required]  
      4.    public string UserName { getset; }  
      5.   
      6.    [Required]  
      7.    public string Password { getset; }  
      8. }  
    3. Create a controller AccountController and add an actionmethod Index and View to show the login screen of the strong type LoginDetail.

      Authorize

      Add the attribute [AllowAnonymous] to the controller class (can be added at actionmethod level also). This is required to exclude these views from being authenticated. Find the code snippet below:
      1. namespace SecurityProj.Controllers  
      2. {  
      3.     [AllowAnonymous]  
      4.     public class AccountController : Controller  
      5.     {  
      6.   
      7.           
      8.         public ActionResult Index()  
      9.         {  
      10.             return View();  
      11.         }  
      12.   
      13.         public ActionResult Login(LoginDetail user)  
      14.         {  
      15.             if (user.UserName == "pradeep" && user.Password == "123")  
      16.             {  
      17.                 System.Web.Security.FormsAuthentication.SetAuthCookie(user.UserName, false);  
      18.                 return RedirectToAction("Index""Home");  
      19.             }  
      20.             return View("Index");  
      21.               
      22.         }  
      23.   
      24.     }  
      25. }  
      In the preceding code if you see a Login action method, I have checked for specific login name and password just for demo purpose and set the Authentication cookie. Why do I need to set this cookie?

      Once this cookie is set, the request will be considered authenticated.

      System.Web.Security.FormsAuthentication.SetAuthCookie(user.UserName, false);

      The first parameter for this method is the value stored in a cookie whereas the second value is to set whether the cookie should be persistent or not.

      Once authenticated, I am redirecting to Home/Index view.

    4. Set the [Authorize] attribute just to the action methods that needs to go through Authentication.

      SetAuthCookie

    5. Execute the project and go to Home/Index. You will observe you are redirected to Account/Login. This is because you have decorated the Action Method or Home controller to [Authorize]. So it tries to authenticate it. Once properly authenticated from the Login/Index view, you are allowed to browse the website.

      Note: Whichever actionmethod that you don’t want to be under Authentication process can be specifeid by adding it with the Attribute [AllowAnonymous].

      If you check the cookie that is created on calling FormsAuthentication.SetAuthCookie
      The method is named .ASPXAUTH as in the following:

      cookie

      I hope you got it. In the same way on the click of logoff you can delete that cookie.

      If you observe, I need to provide an Authorize attribute at the controller level. But I don’t want to do that because my entire website needs to be authenticated and to write my custom logic. For that I can create my own custom filter class inherited from the AuthorizeAttribute class as shown below.
      1. public class MyCustomAuth : AuthorizeAttribute  
      2. {  
      3.    public override void OnAuthorization(AuthorizationContext filterContext)  
      4.    {  
      5.       //Check over here  
      6.       base.OnAuthorization(filterContext);  
      7.    }  
      8. }  
      Register this class in Global.asax.

      cs code

      That’s it. Now your authentication will get executed throughout for all the ActionMethod requests.

    Conclusion

    This completes the article on security in MVC. For authentication, if you select the Internet or Intranet template when creating the new project, then you will get the automated generated classes of model, view, action method already available. But my intention was to show how internally it works. I hope you liked it. Please share your thought or comments, whether good or bad. Sharing is valuable no matter what. Sample code project is available for download.


    Similar Articles