Question

I am writing an application in asp.mvc. I have a view that displays a Product with specific id and on with that view user can modify the Product. There is a dropdown list with colors, that user can select. Range of available colors depends on user's permissions, not all users have access to all colors. When user clicks "Save" button an ajax request us sent to server with ids of Product and selected color. Here is the problem: When user opens the page I check if he is authorized to edit the product with id provided in url and I display only those colors that user can access. But I have no guarantee that user modifies the ajax request sent when he saves the Product. So I can display Product with id 1, and colors with id 12, 13, 14, but user can manually alter the request and change Product id to 3 (which he is not permitted to edit) and select color to 15 (which he shouldn't even see).

In good old webforms this wasn't a problem, because id of product could have been saved in viewstate, and on server side I checked which index of dropdown was selected and then I knew what is the id of selected item (stored in viewstate or controlstate). How do you solve this problem in MVC? Do I have to check if user has access to each element twice, when I display the data and when I receive it, for example in "Save" request?

Was it helpful?

Solution

Even ViewState without protection and care can expose your web server to malicious content. Please note:

Because it's composed of plain text, the view state could be tampered with. Although programmers are not supposed to store sensitive data in the view state (credit card numbers, passwords, or connection strings, for example), it goes without saying that the view state can be used to carry out attacks on the server. View state is not a security hole per se, but just like query strings and other hidden fields you may have used in the past, it's a potential vehicle for malicious code. Since the view state is encoded, protected, and validated, it does provide more security features than other hidden fields that you may use for your own programming purposes.

as Dino Esposito states here.

You've got three options:

  1. Protect (encrypt) your hidden fields (current productId and colors) and validate them on server after a user posts.

  2. Use sessions (store current user's working context, i.e. productId and colors), in case option 3 is too resource consuming or you don't want to maintain huge amount of validation logic on server.

  3. Validate permissions for the objects after user posts. In case option 2 cannot be accepted (you don't use sessions at all).

OTHER TIPS

I agree with RononDex's answer. Session provides you with an easy means of storing data on the server for the user, without exposing that data in way they can manipulate.

So you could store the product ID like so:

Session["ProductId"] = however you get the id.

Plus you can store the colours:

Session["Colours"] = // Whatever you want, an array of int or List<int>

There are caveats with session state though, including that it can be wiped, be it by an expiration of that session (which you can control the number of minutes before that takes place), or an application pool refresh, so bear that in mind.

This might also be good reading for you:

http://brockallen.com/2012/04/07/think-twice-about-using-session-state/

So there are pros and cons to session state. If you decide to not use session state, and instead store the ID values in hidden fields in the HMTL, then please do consider hashing, or encrypting, those ID values so that a user cannot see what they are, or try to alter them.

TempData is used in cases to maintain state, it is stored on the server for one user request.

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