Question

I read an interesting article recently on the CitiGroup Hacking incident http://www.nytimes.com/2011/06/14/technology/14security.html?_r=2&pagewanted=1&ref=technology

This got me thinking, say I have a table of sensitive Employee data in my database with 100,000 rows. The table has a Primary Key called Id, which is an Identity column.

The Employee can log in to the Web Portal and his details are retrieved via a RESTful Url ({Controller}/{Action}/{Id}) e.g. /Employee/Details/31

Now, what's to stop me substituting the {Id} parameter for any parameter (e.g. Id = 32) and retrieving details for Employee #32? Is this what happened with CitiGroup?

How do you prevent this? i.e. where the User has already been Authenticated on the Web Portal but is not Authorized to view other users records? Should I use some other specific 'token' for the customer in addition to the Id ?

Was it helpful?

Solution

This is what I did for exactly the same situation, first I declared an extension to the object:

public static bool Editable(this EXPENSE_OBJ e)
{
    if (e != null)
    {
       UserRepository ur = new UserRepository();

       if (ur.CurrentUser().UserId == e.UserId) //Check if the user owns the claim
       {
           return true; //User owns the claim
       }
       else
       {
           return false; //User does not own the claim
       }

    }
}

And then in the controller:

public ActionResult Details(id)
{
    var item = repo.GetItem(id);
    if(!item.Editable())
    {
         return View("InvalidURL");
    }

    ...

}

OTHER TIPS

You will want to utilize the ASP.NET Roles and Membership API. If you are already doing that then all you need to do to start is mark controller with a IsUserInRole check. You can find more information about the Roles Class here:

MSDN Roles Class

I use a many-to-many table that holds a relationship between the user and the ID of the entities they are allowed to modify. Every time anyone attempts to change one of those entities, I do a check to make sure that they are allowed to do it. I also put a trigger on the table that holds the entities that will delete associated records in that many-to-many table whenever an entity is deleted. This has worked out quite well for me.

Another thing you could do is use a Guid instead of an int for your primary key. That will prevent people from guessing the primary key.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top