Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Security In ASP.NET MVC

0.00/5 (No votes)
29 Jul 2019 1  
Explanation about Authentication, Authorization, XSS, and CSRF (Cross Site Request Forgery)

Introduction

In this article, I would like to explain some security measures that you should be aware of while developing a secure ASP.NET MVC application. In this article, I will be explaining:

  • Authentication
  • Authorization
  • XSS
  • CSRF (Cross Site Request Forgery)

Authentication

When you authenticate a user, you are verifying the identity of a user. If you need to verify a user in an MVC application, it is probably because you are building an application that restricts access to specific users. This is completely separate from authorization, which is determining whether a specific person is allowed to do a certain action.

There are two authentication mechanisms in MVC:

  • Forms Authentication
  • Windows Authentication

Forms Authentication

Form based authentication is providing an input form where users can enter the username and password with accompanying logic in the application needed to validate those credentials. MVC provides a lot of infrastructure support for Forms Authentication. Forms authentication is highly customizable, you can customize everything from the sign in form, to where the credentials are stored and how those credentials are validated. Forms Authentication in ASP.NET relies on cookies by default. Once the user is signed in to an application, the runtime can issue a cookie on the browser. The browser will then send the cookie with every subsequent request to the application. ASP.NET will see the cookie and know that the user is already authenticated and does not need to sign on again.

Note: Word of warning, SSL is required to make Forms authentications secure. If you are running the application over http, anybody snooping the network can see the users credentials.

Windows Authentication

Windows Authentication is also known as integrated authentication because the user components that are built into the Windows operating system are used to authenticate users. Once a user is logged into a domain, Windows can automatically authenticate them into the application. Windows Authentication is commonly used in Intranet Apps that run inside a company's firewall where all of the users are logged in-to a windows domain. It will provide a single sign on experience. They sign on once in a domain and can be authenticated to several intranet apps.

When Do We Choose a Forms Authentication and When Do We Choose Windows Authentication?

  • If you want to build a public website, then Forms Authentication is best because it can be used outside of a windows domain.
  • If you want to build an Intranet application which runs with windows identity, use Windows Authentication.

How is Forms Authentication Configured?

First, we need to change the configuration in web.config like below:

<authentication mode="Forms">
    <forms loginUrl="~/Account/Login" timeout="2880 />
</authentication>

This bit of configuration tells runtime when we need to authenticate the user redirect the browser /Account/Logon. This Account controller and this Logon view as well as some other view allow me to register on site. These things are provided by default in ASP.NET MVC internet template. Everything needed for the Forms Authentications come along with this template.

Selecting the Forms Authentication Template

Open Visual Studio 2010 >> New Project >> Select ASP.NET MVC4 Web Application and Click OK.

And then select Internet Application Template which gives us to everything needed for the Forms Authentication like AccountController, Views, etc. and then click OK.

Authorize

[Authorize]
public ActionResult Index()
{
    return View();
}

The Authorize attribute doesn’t really care about how we authenticate a user. We can use a Form Authentication or Windows Authentication. All authorize cares about is that the user has an identity and we know who they are and it’s not going to let an anonymous user get in to the Index action. When we try to take an index action without authenticating, it automatically redirects to Account/Logon because the user has no account in this application. So we need to register to Logon.

How We Authenticate with Windows Authentication?

First, we need to change a little bit in the configuration section like below in the web.config file.

<authentication mode="Windows">
    <!--<forms loginUrl="~/Account/Login" timeout="2880" />-->
</authentication>

Then apply the authorize attribute to the index action:

[Authorize]
public ActionResult Index()
{
    return View();
}

You can apply authorize filter to an individual action method or to a controller. When you apply a filter to a controller, it works as though you had applied it to every action method in the controller class applied the Authorize filter to the class, so all of the action methods in the Account controller are available only to authenticated users.

In order for Windows integrated authentication to work, we need to enable Windows Authentication in IIS Express, or else we get the below error and this is the scenario you commonly face in today’s server configuration.

Server programs’ like Web services and Database services typically have features turned off by default to reduce the attack surface. If we want to Windows Authentication to work, we need to turn it on.

Go to Document >> IISExpress >> config >> applicationhost.config file and Windows Authentication enabled to true.

You can take authentication details like below:

Authorization

The authorize attribute also allows you to set some parameters to enforce authorization rules. First, we need to know the user’s identity and then we can say only the specific identities to allow accessing these actions.

[Authorize(Users = "jameel,vinayan")]
public ActionResult Index()
{
    ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
    
    return View();
}

The Authorize attribute also allows you to specify the Roles. Windows Authentication (by default) maps to Windows groups on server or groups configured in the active directory. You can put roles like below:

[Authorize(Roles = "@domainname\username")]
public ActionResult Index()
{
    ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
    
    return View();
}

In Forms Authentication, ASP.NET has a role provider. By using these, you can store, manage roles in a SqlServer database. These can be configured in the application by default. The easiest way to do that is use the below button in the solution explorer.

It launches ASP.NET configuration tool. This is the tool you are only going to use in the local development machine. It’s going to look in the web.config location and use the same application services database as that Form Authentication provider of using that is already configured inside of there. You can add, manage roles from here. While doing these, it automatically maps to db we are configured in the web.config file.

XSS

There are some specific threats we will face. One popular attack of this phase is Cross Site scripting attack or XSS. In Cross scripting attack, the malicious user will try to have your website load a malicious script into the user’s browser. It could be a malicious script, Active-X control, and even some malicious HTML. The malicious scripts can theft the cookie, Modify user settings, Download Malware, or Modify content. One of the worst cross site script attack is Account Hijacking; the malicious users can access the user’s credentials and personal information.

Once this happens, your users become vulnerable to any number of problems.

Demo

This is a simple application for saving employee information. I am putting some HTML tags like that I am from <em>India</em> and then when I try to save this, ASP.NET automatically rejects this request to prevent Cross site scripting attack because the ASP.NET is going to look for anything that resembles the HTML and just rejects the request. Actually, there is nothing wrong with the emphasis tag but ASP.NET is not trying to make a distinction here anything that looks like HTML is going to be rejected.

Sometimes, users need to upload some HTML to the server then there are always circumvents to this request validation. You have to be extremely careful. One option is put ValidationInput attribute to the destiny here in Create action.

So you can successfully process this request.

Now we can have a problem that HTML encoded here. This is because razor is going to encode everything by default, which is good. There is another defense against the cross site scripting and we can fix that easily. However, the validate input false is completely disabling the check for cross site scripting, malicious HTML, and really we only need HTML inside of one specific property. So you can allow HTML to one property using the AllowHtml attribute. Also, some changes need to be made, remove ValidateInput attribute from the Create action and also make sure that we should pass the EmployeeViewModel class as an action parameter, that means model binding will take place and will move the HTML to that property. Also, one change in the view to show the HTML without encoding by putting ViewData in Html.Raw helper.

And then again, going to save one more and display the ViewData in the same view containing HTML tag.

Anti XSS Library

Someone comes to a form and enters some script like below:

It’s also more malicious. Fortunately, Microsoft provides a library for prevent this. You can download it via nugget or Library Package Manager Console (Visual Studio>>Tools>>Library Package Manager>>Package Manager Console and type Install-Package AntiXSS and press enter).

What I am going to do is I am putting a line of code in the below Edit action post method.

And this code will remove all the malicious things.

Cross Site Request Forgery

Cross Site Request Forgery is a dangerous and an extremely major attack. Imagine a user comes into the site, trying to update some information that requires authentication before they are allowed to perform the update. Once the user logs in the Form Authentication, your site will send the users browser an authentication cookie and every subsequent request of the site, the users browser will send that cookie along and ASP.NET will see the user is already being authenticated. There is nothing wrong with the browser to sending the cookie along this is how the browser and cookie works - that means the user doesn’t need to enter the username and password in every single request they make. They authenticate themselves once and the cookie will allow them to remain authenticated at least for the duration of the session.

Then What Is the Problem?

If the user visits some other site or is strict in picking up some HTML from a malicious source which had bad intentions, then this malicious source can provide a form, just like a form that our application would give to the user and then if the user submits the form, the call again will be authenticated because the authentication cookie be given to the users' browser. Always travel along every request and it will save the information into the database like we always do once we have authenticated the request. Only the information in the request probably is in something the user wants to submit. Someone tricked the user into transferring money or editing their account. The problem here is not to simply say we need the user to be authenticated when submitting some information. We also have to be checking the information that the user is submitting coming from a form that our application presented to the user. We want to be preventing them when submitting the form from a malicious source.

Demo

To demonstrate a CSRF, I am applying the authorize attribute to my two Edit action methods of my application.

//
// GET: /CSRF/Edit/5
[Authorize]
public ActionResult Edit(int id = 0)
{
    Employee employee = db.Employees.Find(id);
    if (employee == null)
    {
        return HttpNotFound();
    }
    return View(employee);
}

//
// POST: /CSRF/Edit/5

[HttpPost]
[Authorize]
public ActionResult Edit(Employee employee)
{
    if (ModelState.IsValid)
    {
        db.Entry(employee).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(employee);
}

I can save, edit the records because I had already authenticated. Below is a sample record that I had saved into the database successfully.

In the developer point of view, we are confident that I had authorized an attribute in place for preventing malicious user from editing an Employee details.

Watch would happen that I logged in as a user. I came across an interesting link in my system.

Maybe this link will you get from an email or from another website or some other areas of internet. Now I am going to click the link and see a page will come up.

Now look at the record that we had saved earlier, it has changed. What happened?

Look at the source code of the link:

Look at the action that the form points to which has the same URL where the employee is posted. The form contains all of the input needed to complete the request and also at the bottom some line of JavaScript for automatically submitting the form when the page loads.

How Can We Prevent This?

Use @Html.AntiForgeryToken() inside the form tag. This token will add a hidden input value that is unique to the browsing session. Also send a matching value in a cookie to the users browser so the user accepts this cookie and that something malicious website would not be able to do.

Also you should put an attribute ValidateAntiForgeryToken for matching the form value and cookie value:

I am again going to edit my record that the malicious user had done. Now I am going to click that link again and the ASP.NET MVC throws an exception that AntiForgeryToken is not supplied or invalid.

Hope you enjoyed my article ... Expecting your valuable suggestions… enjoy programming!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here