1

I'm looking for suggestions, or really good tutorials on how to handle passing ids back and forth in a secure manner from client to server, I'm not passing user ids or anything like that, however I might pass an id for Items table row. I would like to hide these ids from users. I wish i could avoid putting them in the page altogether however considering they are the pk, I have no choice, but to ping pong the value back and forth from client to server.

Thanks for any help.

edit: I plan to check whether or not the user has permission to do such actions, however I would still like to hide the data.

nagates
  • 620
  • 13
  • 40

4 Answers4

6

Easy Suggestion:

1) Add a guid column to your tables that's generated (default value: new id()). Create an index on the guid column. Pass the guid back and forth rather than your PK.

2) Does this completely secure your ids? No. But it prevents users from guessing at numeric PKs.

3) Always sanity check that the Authenticated user has access to the record.

Brent Anderson
  • 966
  • 4
  • 6
  • Totally agree - the risk here is what's called Insecure Direct Object reference (see https://www.owasp.org/index.php/Top_10_2010-A4) and those are the correct mitigations. Even if you do encrypt you should still check that the correct user has permissions to access the resource being displayed. – blowdart Jan 22 '12 at 22:46
3

You really should just do your security on the server. Any record the user has access to should be available, and any record they don't have access to shouldn't. It doesn't matter if they know what the ID is, because they have access to the data anyways. Anything they can do by hacking, they can do in the UI.

As such, it simply makes no sense to try to hide them.

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
2

You can use the MVC Security Extensions project https://mvcsecurity.codeplex.com.

Say the field you want to protect is Id...

On you controller post method add:

[ValidateAntiModelInjection("Id")]

Within your view add:

@Html.AntiModelInjectionFor(m => m.Id)
@Html.HiddenFor(m => m.Id)

On post your Id field will be validated.

Andrew
  • 5,525
  • 5
  • 36
  • 40
2

As you've alluded to, it's not an ideal practice to output the PK of item table rows out to the View, as if they're in the HTML of the page, they are viewable.

If I understand correctly, by '[hiding] these ids from users' I'm guessing you mean obfuscating the IDs somehow so even if they are taken from the view's HTML, they mean little in their individual context.

One way you could achieve the above is by using a ViewModel to output your bound data to the view, but in your specific ViewModel class, you could have some custom property logic to encode the PKs with an AES (two-way) encryption algorithm, with the salt for the encryption being something only known to you (and your server).

That'd be one way of 'protecting' the PKs in the view.

With such an approach, you may have to factor in the performance overhead though of encrypting/decrypting the PKs when this data is ping ponged back and forth!

This may be of interest if you do go down the encryption route:

Simple insecure two-way "obfuscation" for C#

You could also achieve some greater opacity without encryption by having an in-memory (cache or session data) key-value lookup that outputs arbitrary numbers as IDs to the view for each of your table items and, when retrieved from the view, the PK is reverse looked up from the in-memory collection.

Community
  • 1
  • 1
Henry Mori
  • 51
  • 4
  • This might be a little misleading Henry. Just to clarify MD5 is a one-way cryptographic hash function. It can't be used to encrypt or encode data in a way that can be decoded. It produces a hash value that can be used to validate data. – Sam Greenhalgh Jan 22 '12 at 20:55
  • You are absolutely correct @zapthedingbat, thanks for correcting my misconception! In that case, would the above stand with the use of a two-way encryption algorithm like e.g. http://stackoverflow.com/questions/165808/simple-2-way-encryption-for-c-sharp – Henry Mori Jan 22 '12 at 21:17
  • Using a hash is a very good way of ensuring that values like this that are presented and must be played back have not been tampered with. That's exactly the way that the ViewState validation in ASP.NET works. If you are only interested in ensuring that the values have not been changed then hash validation is all you need, however if you need to stop the user from knowing what the value is then you would have to look at encrypting the value using something like the AES cryptography routines available in the Framework. – Sam Greenhalgh Jan 22 '12 at 21:20
  • Thanks @zapthedingbat, I've corrected/updated my response in line with your feedback. Thanks for the feedback and correction! :) – Henry Mori Jan 22 '12 at 21:23