views:

37

answers:

2

I am looking for some best practices when is comes to creating EditMoels and updating data in an ASP.NET MVC app. Lets say I have a Url like so /Post/Edit?Id=25

I am ensuring the user has permissions to edit the specific post by Id on the Get request and the same for my Post in the controller. I am using the ValidateAntiForgeryToken.

Questions: Should I include the Id property in my EditModel? If so, Should I encrypt it?

The problem is I can use FireBug to edit the Id hiddedinput and edit a different post as long as I have permission to do so. This is not horrible, but seems wrong.

Any help would be great!

A: 

I don't think you should worry with that, if the user does what you said, i suppose that you'll know who edited what, so if he edits the wrong post, doing as you said, you can always remove his edition rights...

If you can't thrist your users, don't let them edit anything...

moi_meme
It is not so much that I "Cant" but more that I shouldn't. I don't think this site just trusts every user, but still allows everyone to edit their posts and comments.
Paul
A: 

There are several ways to prevent this.

The first - don't send sensitive data to the client at all. Keep the post id in session variables, so the user can never edit it. This may or may not be an option depending on your architecture.

The next approach is to convert the direct reference to an indirect one. For example, instead of sending postids = {23452, 57232, 91031} to the client to render a drop-down list, you should send an opaque list {1,2,3}. The server alone knows that 1 means 23452, 2 means 57232 and so on. This way, the user can't modify any parameter you don't want him to.

The last approach is including some kind of hash value that adds as an integrity check. For example, suppose you have 3 hidden fields in a html page - {userId=13223, postId=923, role=author}. You first sort the field names and then concatenate the values to get a string like postId=923&userId=13223&role=author. Then, append a server secret to this string, and hash (SHA-1 or MD5) the entire string. For eg. SHA-1('postId=923&userId=13223&role=author&MySuperSecretKey'). Finally add this hashed value as a hidden parameter. You may also want to add another hidden field called ProtectedParameters=userId,postId,role.

When the next request is made, redo the entire process. If the hash differs, balk the process.

Security wise, I have listed the options in decreasing order. At the same time, its probably in the increasing order of convenience. You have to pick the right mix for your application.

sri