0

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?

Community
  • 1
  • 1
Leblanc Meneses
  • 3,001
  • 1
  • 23
  • 26

3 Answers3

1

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.

Adam Tuliper
  • 29,982
  • 4
  • 53
  • 71
  • So if ValidateOptionInjection encryption key included ActionName, User_Id, TenantDataGroup_Id, assembly version, deployment salt? The key alone would make each dropdown encryption standalone on per user basis. The benefit of this generalized solution is an app can be secured with relatively little effort. The additional server validator can always be added but from the start this will protect most dropdowns and deter a larger set of individuals tampering with forms. – Leblanc Meneses Aug 26 '13 at 17:38
  • It would, note though that if you refactor and any of the above data changes your data would fail. So if a user is editing a page while you deploy a new version, the post back to the server then would fail. I'm not sure if your application allows such a thing, but keep that in mind. Web forms tracked all values, which when you wanted to dynamically add values to a dropdown via client script, it became difficult. – Adam Tuliper Aug 27 '13 at 08:19
0

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.

Fabio S.
  • 460
  • 7
  • 22
0

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.
 }
Leblanc Meneses
  • 3,001
  • 1
  • 23
  • 26