Thursday, April 30, 2015

Insecure Object Reference in MVC

Today, we are going to discuss what insecure object reference is in MVC and how to prevent it.

Insecure Object Reference in MVC

This occurs when a developer exposes reference to an internal object. Without access control check in place, the attacker can manipulate the reference to retrieve data which he is not allowed to access.
Suppose, you have a web application which displays customer records. As an Admin, I can access all the customer records but as a regular customer, I can access only my record.

So as a regular customer, I see customer list page as:


When I view the Details page I see:




So I see my own details and that's perfectly fine. However, note the URL, it's like: /Customers/Details/1. The attacker can easily guess that number 1 is the customer id. So he can try to change the customer id and re-sub,it the request. So when submits the request like this: /Customers/Details/2, he gets:






So the attacker is able to access the record which he was not allowed to access. Imagine it can have some sensitive details like credit card information, address, etc. The reason why this could happen is that unencrypted Customer Id is exposed to the client and we don't have a server side check for permissions if the user is allowed to see the customer details or not.

 How to Prevent

In order to prevent it, one approach is to encrypt the customer id. In this way, it would be difficult to guess the other customer's id and hence access their records. However, this approach is not foolproof. We should have server side check to see if the current user is allowed to access the customer details or not. So our action method might look like this:


public ActionResult Details(int id)
        {
            if (!IsEmployeeVisible(SessionUser.UserId, id))
            {
                return new HttpStatusCodeResult(HttpStatusCode.Unauthorized);
            }
            Customer customer = db.Customers.Find(id);
            if (customer == null)
            {
                return HttpNotFound();
            }
            return View(customer);
        }

The method IsEmployeeVisible should check whether the id requested is visible to the logged in user. If it's not visible then the details are not returned.

Conclusion

In this post, we saw how a malicious user can access records which he is not allowed to access if we don't have server side checking. We should have access checks inside action methods whether it's a GET or a POST or an AJAX call.

For future updates to my weekly blog, please subscribe to my blog via the "Subscribe By Email" feature at the right and follow me on twitter. Until then Happy Coding :)


Thursday, April 23, 2015

Open Redirection Attack in MVC

In today's blog post I am going to discuss open redirection attack in MVC applications.

Open Redirection

Any application that redirects the user to a URL that is coming in as query string or form data can be vulnerable to open redirection attack.

If we try to visit a controller action with Authorize attribute and we are not logged in, we are redirected to the login page. This redirection looks like this:

/Account/Login?ReturnUrl=%2FExpense%2FIndex.


Once we login we are redirected to the /Expense/Index page, as mentioned by the ReturnUrl.

Imagine, if you received an email which has a hyperlink like this:

http://www.mygoodbank.com?ReturnUrl=www.mugoodbank.com  


(Please note the return Url has a different spelling). The Url might look similar but is controlled by the attacker.

So the user visits the page related to mygoodbank.com and enters the login name and password. Once the user enters the credentials, he is redirected to mugoogbank.com which the attacker has made sure that the page looks similar to the login page of my mygoodbank.com. The victim might think that he is redirected to the login page again because he mistyped the credentials. So the user types in the username and password again (this time on malicious website) and clicks on Login. The attacker can save the username and password and redirect the victim to the legitimate website. The legitimate website had already authenticated the user on previous attempt, so the user sees the required page that he was trying to access.

In this way, the attacker has stolen the user credentials without the victim ever knowing about it. Mixing a little social engineering with technical ability helps the attacker to accomplish this easily.

How To Prevent?

Whenever we redirect the user to any URL in our application, we must check that Url is local or not. If not, we must raise an exception that open redirection attack was attempted.

In MVC5, the AccountController Login method has:

return RedirectToLocal(returnUrl);


This RedirectToLocal tests whether the URL is local or not using Url.IsLocalUrl() method. Similarly, if we are redirecting the user to any page based on the input coming from the user, we should test if the URL is local or not.

Conclusion

MVC1 and MVC2 were vulnerable to this attack as they were not checking for the local URL. But MVC3 onwards, the AccountController checks for local Url. In our application, if we are redirecting anywhere we should make sure that the user is being redirected to local URL only.
For future updates to my weekly blog, please subscribe to my blog via the "Subscribe By Email" feature at the right and follow me on twitter. Until then Happy Coding :)

Thursday, April 16, 2015

Over Posting Attack in MVC

In today's blog post, I am going to discuss the over posting attack in MVC application.

Over Posting

Model-binding is a useful and powerful feature of MVC. It automatically handles the mapping of form input to model properties. This prevents me from writing all that mapper code again and again. However, it opens up the vulnerability which allows the attacker to submit extra data with the form to populate model properties which were not intended to be changed.

Let's take a look at an example to understand this. Suppose, we have a class called Expense:

public class Expense

    {

        public int ExpenseId { get; set; }

        public int EmployeeId { get; set; }

        public string EmployeeName { get; set; }

        public int AmountMoney { get; set; }

        public bool IsApproved { get; set; }

    }


Suppose, we have a View called Edit.cshtml which exposes all the properties to be edited. Suppose there is a logic on when to allow the IsApproved flag to be edited. We show the IsApproved checkbox to only HR users and not to other employees.
Similar to standard controller, we have Edit action method in ExpenseController like this:

[HttpPost]

[ValidateAntiForgeryToken]

public ActionResult Edit(Expense expense)

{

        //save expense to database 

}

For regular employee, the IsApproved checkbox doesn't appear on the Edit View. So ideally he should not be able to Approve or Disapprove the expense request.




However, a malicious user can easily update the value of the flag as per his convenience. In order to demo this attack, I installed a plugin on my Chrome called Request Maker. It allows me to edit/ send any HTTP request.



So what I did was just added the flag IsApproved and set the value to true. And voila, the Expense is approved.


The reason why I was able to accomplish this was because model binding in ASP.NET MVC tries to bind the data submitted to model properties based on their names. If it matches, it is accepted. And once it reaches the model, we simply save everything to the database.

How to Prevent?

 

Bind

Using Bind attribute is a good way to prevent over posting attack. Using Bind attribute, we can include or exclude specific properties which are supposed to bind.

public ActionResult Edit
([Bind(Include = "AmountMoney")]Expense expense)
{

    ....... 

} 

In this example, only one property is added. So now, no matter how many values are posted from the client, we will get only one property out of those i.e. AmountMoney. All other properties will be ignored by the binding.

Similarly, we can also Exclude certain properties, if needed.

 

ViewModel

Using ViewModel for each view also helps us in preventing this attack. The ViewModel should have only the properties which are supposed to edited by a particular view and no other properties. So these can be mapped to specific properties of the Model before its saved to the database. It is a good practice to have view models for views and to not use model entities for the view.

 

Server-Side Checking

On the HttpPost action method, we can explicitly check the value of the properties. We can write custom code to check if the current user is of employee role then use the database value of IsApproved flag else if the user is HR user role then use the value posted. This is feasible if the check needs to be done once in a while. This might get difficult to maintain pretty soon.

 

Conclusion

In this blog post, we talked about what over posting attack is and how it can be harmful. We also discussed some of the ways to prevent it.
For future updates to my weekly blog, please subscribe to my blog via the "Subscribe By Email" feature at the right and follow me on twitter. Until then Happy Coding :)

Thursday, April 9, 2015

Console Tab in Chrome Developer Tools

Console Tab

In a previous blog post, I talked about Elements tab in Chrome developer tools and explained how they are useful in debugging. Today I am going to talk about some features of the Console tab which are again very helpful for debugging web applications.

Log

Gone are the days, when people used to put alert() statements everywhere throughout the code in order to check variable values or control flow in the JavaScript code. Now we can use console.log() statements in order to see what's going on in the client side code. We can output all the values and the results are visible in the Console tab.

Warn

If we want to output the message as a warning, we can use console.warn() statement. These messages appear with a yellow warning sign. These are useful if you want to put some messages for less likely scenarios. We can even filter all the warnings together.

Info

Messages output using console.info() statement come with a blue info sign. These can also be filtered.

Error

Using console.error() statement we can output the error in the console tab. It appears with a red color. We can also navigate to where the error occurred directly as the source is displayed right next to the error. 

Assert

console.assert can be used for testing. For example,

console.assert(10 == 5*4,"Items Not Equal");

So it will break at this point and take us to the script where the test failed.

Group

Using a lot of console.log statements can become unwieldy. So in order to manage log statements better, we can group them together.

        console.group("Group Example");

        console.log("Message 1");

        console.log("Message 2");

        console.groupEnd(); 
So here the 2 log messages will come under a single group. Similarly, we can also use console.groupCollapsed() if we want the group to appear as collapsed.


Time

In order to find the time taken by a snippet of code, we used to get the current time before and after and subtract the two timestamps. Using console.time() makes it more convenient and quicker to find out the time.

        console.time("Loop Time");

        for (var i = 0; i < 100000; i++) {}

        console.timeEnd("Loop Time"); 

console.time() denotes the starting point and console.timeEnd() denotes the end point.

dir

console.dir() prints the JSON representation of the supplied object. For example,

console.dir(document);

will print the whole document's JSON representation.

dirxml

console.dirxml() prints the XML representation of the supplied object.

console.dirxml(document);

will print the whole document's XML representation.

Count

Using console.count we can keep the count without maintaining a counter explicitly. Another very handy feature for debugging.

Profile

Using console.profile() we can start and using console.profileEnd() end profile. Profile is pretty useful to find out what all code got executed and how much time each part took. Its similar to SQL Server profiler.

Trace 

In order to see the stack trace I can put this statement anywhere in my JavaScript code. This will show me the stack trace of who called this statement.

Execute JavaScript

Other than these useful commands, we can also execute any JavaScript code in the console tab directly. I can inspect or change the values of any variables or elements.

Conclusion

In this post, we discussed about different console tab commands and how they can be helpful in debugging and development. Once you start using it, you will realize how useful it is in everyday development and debugging.
For future updates to my weekly blog, please subscribe to the blog and follow me on Twitter. Until then Happy Coding :)




Thursday, April 2, 2015

Cookie Stealing Attack in MVC Application

In today's blog post, I am going to discuss what cookie stealing attack is and how we can prevent it.

Cookie

Cookie is a small piece of data sent by a web server to a web browser. The browser stores this data in a text file. This data is sent by the browser to the web server each time it requests a page from that server.
Cookies store information like your site preferences or history so that they can customize the page for you, every time you request it. So that information is usually not what attacker cares about. Cookies are also used to store information that uniquely identify the user such as the Authentication Ticket. That's more luring to the attacker ;) If the attacker can steal someone's authentication cookie they can simply get access to the complete account.

Cookie Stealing using XSS

In order to steal the cookie, the attacker can write a script which reads all the cookies and sends it to the attacker. If you search about it on google, you can find plenty of scripts that read all the cookies and send it to a specific server. I also discussed about XSS attack in my previous blog post here. If the site is XSS vulnerable, the attacker's task is made easy. He can simply get the script executed on anyone's machine and get all the cookies.
Once the attacker gets the authentication cookie, he can copy the Session Id/ Username, etc and plug that information into his own browser and get access to the victim's account. Isn't it simple?

How to Prevent?

In order to prevent the scripts to access the cookies we need to set the flag called HttpOnly to true. This allows the scripts to be accessed only by Http and disables all kinds of script access. We can set this flag at the application level in system.web section in web.config like this:
 
<httpCookies domain="" httpOnlyCookies="true|false" requireSSL="true|false" />

If we need to set it at per cookie level, we can set it like this:

Response.Cookies["ImpCookie"].HttpOnly=true;

Conclusion

Cookies can store valuable information and should be protected. We should set the cookie access to HttpOnly in order to prevent their access from malicious scripts.
For future updates to my weekly blog, please subscribe to the blog and follow me on Twitter. Until then Happy Coding :)