solution for: select input, dropdown tampering prevention

882 views Asked by At

for hidden field tampering protection: Id, RowVersion, I use a version of Adam Tuliper AntiModelInjection.

I'm currently investigating a way to prevent tampering of valid options found in select lists/drop downs. Consider a multitenant shared database solution where fk isn't safe enough and options are dynamic filtered in cascading dropdowns.

In the old days of ASP.NET webforms, there was viewstate that added tampering prevention for free. How is select list tampering prevention accomplished in ajax era? Is there a general solution by comparing hashes rather than re-fetching option values from database and comparing manually?

Is ViewState relevant in ASP.NET MVC?

3

There are 3 answers

0
Fabio S. On

Leblanc, in my experience, client side validation has been used mostly for user convenience. Not having to POST, to only then find out that something is wrong.

Final validation needs to occurs in the server side, away from the ability to manipulate HTML. Common users will not go on to temper with select lists and drop downs. This is done by people trying to break your page or get illegal access to data. I guess my point is final security needs to exist in the server, instead of the client side.

2
Adam Tuliper On

If you can, the single solution here is to filter by the current user ids permission to that data, and then those permissions are validated once again on the save.

If this isn't possible (and there are multiple ways server side to accomplish this via things like a CustomerId fk in your records, to adding to a temporary security cache on the server side, etc) , then a client side value can provide an additional option.

If a client side option is provided like was done with Web Forms, then consider encrypting based on their a.) User id plus another key b.) SessionId (session must be established ahead of time though or session ids can change per request until session is established by a value stored in the session object. c.) Some other distinct value

HTTPS is extremely important here so these values aren't sniffed. In addition ideally you want to make them unique per page. That could be the second key in A above. Why? We don't want an attacker to figure out a way to create new records elsewhere in your web app and be able to figure out what the hashes or encrypted values are for 1,2,3,4,5,6,etc and create essentially a rainbow table of values to fake.

0
Leblanc Meneses On

I think a global solution could be created given a few assumptions. Before i build anything I'll like to propose an open solution to see if anyone can find flaws or potential problems.

Given all dropdowns retrieve their data remotely. - in an ajax era and with cascading boxes this is now more common. (We are using kendo dropdowns.)

public SelectList GetLocations(int dependantarg);

The SelectList will be returned back as json - but not before having newtonsoft serialization converter automatically inject: (done at global level)

  1. EncryptedAndSigned property to the json. This property will contain a Serialized version of the full SelectList containing all valid values that is also encrypted.
  2. EncryptedName property to the json. This property will have the controller actionname - For this example the EncryptedName value would be "GetLocations"

When the http post is made EncryptedName : EncryptedAndSigned must be sent in the post also. For this JSON POST example it would be:

{
 Location_Id: 4,
 GetLocations: 'EncryptedAndSigned value'
}

On the server side:

 [ValidateOptionInjection("GetLocations","Location_Id")
 public ActionResult Update(Case case)
 {
    //access case.Location_Id safety knowing that this was a valid option available to the user.
 }