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 :)


No comments:

Post a Comment