tags:

views:

1709

answers:

6

In ASP.NET MVC (default routing), I'd like to use a URL like this to return a View with a form to edit a customer:

/Customers/Edit/5

I need to make use of CustomerId=5, but I don't want to permit a customer to change it. Right now I make the id hidden using:

<%= Html.Hidden("CustomerId") %>

This accomplishes what I want, but I'm under the impression that hidden form variables are not secure and can be manipulated by the end user.

So, what's the best way to allow a customer to edit their information but not their ID?

+3  A: 

You don't do any real security at the browser side. You can put the customer ID in the query string, but the server should validate whether or not they are really allowed to edit that customer. If not, return an error.

1800 INFORMATION
+5  A: 

Check permissions in your controller action (/Customers/Edit) before you display the according view. Note that the problem here is not with your hidden field at all: a user could just type "http://yoursite.com/Customers/Edit/10" in his browser. So you have to check in your action whether the user is really allowed to edit requested customer's details, no matter how he invoked the action.

Dmitry Perets
I see how to configure a controller action so that only authorized users can see a View for a particular ID, but I don't see how to prevent a user from changing that ID. For example, a user might be authorized to view /Customers/Edit/10, but then they could change the ID when submitting the form and edit an ID they weren't authorized to see in the first place (e.g. /Customers/Edit/11). I guess I need to check the submitted form to make sure the ID is what I sent them in the first place.
Slack
You have to check that the currently logged in user has permission to view/edit the requested ID. So in your controller action you retrieve the username (using Thread.CurrentPrincipal.Identity.Name for example) and check in your db whether this user is allowed to do what he tried to do (view or edit, depending on requested action). So if the user changes the ID, he still can't view\edit what he is not allowed to. Actually there is no reason for him to even try to change the ID...
Dmitry Perets
+1  A: 

There are two aspects. I'm not sure which you were directly asking about, but they are both important:

  • For any given user, they may not be allowed to edit all customers. So, as Dmitry suggests, your controller action for the form post needs to look at the customer they are trying to edit a and verify that the logged in user is actually allowed to edit that customer. You probably also want to do a similar check in the controller action that generates the edit form in the first place and don't even let them get to the form if they are not allowed to edit the requested customer.
  • For a given user and a given customer, you probably don't want the user to be able to change the customer ID. If you are using the UpdateModel method in your POST controller action, you need to use the property whitelist parameter and exclude the ID property so that the user an not change the ID. Even if they change the value of the hidden field, the changed-value will be ignored by UpdateModel via the whitelist.
Erv Walter
+1  A: 

I am having the same problem and I believe the solution involves using surrogate keys. In each table where I have an ID column, I also add a Key column that is a Guid (uniqueidentifier in SQL server). Now, when doing joins or any internal logic I use the ID but the controller all use the Key. Since it's a Guid, it's difficult to guess what another record's Guid is.

Alternatively (or in addition to the above) you could encrypt the hidden field according to This article

Loki Stormbringer
A: 

My solution was to use the Tamper Proofing code from Steven Sanderson's ASP.NET MVC book. The idea is that you create a hash of any hidden form field you want to tamper proof:

<%= Html.Hidden("CustomerId") %>
<%= Html.Hidden("CustomerIdHash") %>

When the form is submitted, Steven's code then computes another hash of CustomerId and makes certain it equals CustomerIdHash. If it does, then no tampering has occurred. It's great code, and worth the price of the book.

Slack
Make sure you salt that hash, otherwise you've gained nothing! (I trust the book explains this in more detail.)
teedyay
+1  A: 

Tamper proofing hidden fields is all well and good but that is still security through obscurity. It is always best to secure a web site, more specifically MVC, by securing the controllers and actions. Then the user can tamper all they want and they are not going to get anywhere.

eccsolutions