Exposing Database IDs to the UI

Go To StackoverFlow.com

6

This is a beginner pattern question for a web forms-over-data sort of thing. I read Exposing database IDs - security risk? and the accepted answer has me thinking that this is a waste of time, but wait...

I have an MVC project referencing a business logic library, and an assembly of NHibernate SQL repositories referencing the same. If something forced my hand to go and reference those repositories directly from my controller codebase, I'd know what went wrong. But when those controllers talk in URL parameters with the database record IDs, does it only seem wrong?

I can't conceive of those IDs ever turning un-consumable (by MVC actions). I don't think I'd ever need two UI entities corresponding to the same row in the database. I don't intend for the controller to interpret the ID in any way. Surrogate keys would make zero difference. Still, I want to have the problem because assumptions about the ralational design aren't any better than layer-skipping dependencies.

How would you make a web application that only references the business logic assembly and talks in BL objects and GUIDs that only have meaning for that session, while the assembly persists transactions using database IDs?

2012-04-05 19:11
by nik.shornikov


3

You can encrypt or hash your ids if you want. Using session id as a salt. It depends on the context. A public shopping site you want the catalog pages to be clear an easily copyable. User account admin it's fine to encrypt the ids, so users can't url hack into someone else's account.

I would not consider this to be security by obscurity. If a malicious user has one compromised account they can look at all the form fields, url ids, and cookie values set while logged in as that user. They can then try using those when logged in as a different user to escalate permissions. But by protecting them using session id as a salt, you have locked that data down so it's only useful in one session. The pages can't even be bookmarked. Could they figure out your protection? Possibly. But likely they'd just move on to another site. Locking your car door doesn't actually keep anyone out of your car if they want to get in, but it makes it harder, so everyone does it.

2012-04-05 21:11
by Brian White
You gave me lots to think about. Can you throw any suggestions out for how to implement the mapping and where to store it? Is "session" indeed the best place in ASP - nik.shornikov 2012-04-06 19:06
"the mapping"? Not clear on what you're looking for. The field protection? I was just suggestion you do an encrypt function that takes: FieldName, FieldValue, SessionID. Then when you decrypt you also need to supply all 3 to decrypt. So someone in another session is unable to hijack that value at all. Should be all you need for url parameters. If you ever need support for sessionless pages you can have a hardcoded value used instead of session id, not as secure but sessionless pages shouldn't access anything to sensitive - Brian White 2012-04-06 22:09
I spaced on the crux of your answer, salt with session: there is no need to store/manage mappings at all -- they'd persist for exactly as long. This is awesome. Thank you - nik.shornikov 2012-04-06 23:36


3

I'm no security expert, but I have no problem exposing certain IDs to the user, those such as Product IDs, User IDs, and anything that the user could normally read, meaning if I display a product to the user, displaying its Product ID is not a problem.

Things that are internal to the system that the users do not directly interact with, like Transaction IDs, I do not display to the user, not in fear of them editing it somehow, but just because that is not information that is useful to them.

Quite often in forms, I would have the action point to "mysite.com/messages/view/5", where 5 is the message they want to view. In all of these actions, I always ensure that the user has access to view it (modify or delete, which ever functionality is required), by doing a simple database check and ensure the logged in user is equal to the messages owner.

2012-04-05 19:25
by Matthew
Yes, obfuscating URLs to not expose database IDs is just a form of security through obscurity. You shouldn't rely on obfuscated URLs for your security. You still need to actively implement some other form of permissions management that is appropriate to your application - Charlie Kilian 2012-04-05 19:46
You shouldn't rely only on it. But you don't need to make things easy for hackers either - Brian White 2012-04-06 17:52
I definitely performed the sanity check exactly along those lines: you are displaying everything from row 5, who cares if you also say, "if you needed to know this is row 5". My problem was mainly this: that my viewmodels have a 1-1 to my BL objects and a 1-1 to my ORM entities is a coincidence I don't want to make a convention - nik.shornikov 2012-04-06 23:43


2

Be very very very careful as parameter tampering can lead to data modification. Rules on 'who can access what ids' must be very very carefully built into your application when exposing these ids.

For instance, if you are updating an Order based on OrderId, include in your where clause for load and updates that : where order.orderid=passedInOrderId and Order.CustomerId=

I developed an extension to help with stored ids in MVC available here:

http://mvcsecurity.codeplex.com/

Also I talk about this a bit in my security course at: Hack Proofing your ASP.NET MVC and Web Forms Applications

2012-04-05 20:01
by Adam Tuliper - MSFT
Your codeplex project looks very similar to a technique we use here. But we don't use a machine key, we use a key from a database backed session, so it works on all the different ui tier boxes. I am rather surprised at everyone who thinks they will never have any bug where they overlook perfect user access validation. That's just not the real world - Brian White 2012-04-06 14:08
Good suggestion, and it will do permission/role checks in BL, where it operates in real IDs - nik.shornikov 2012-04-06 19:04


1

Other than those responses, sometimes it's good to use obvious id's so people can hack the url for the information they want. For example, www.music.com\artist\acdc or www.music.com\arist\smashing-pumpkins. If it's meaningful to your users and if you can increase the information the user understands from the page through the URL then all the better and especially if your market segment is young or tech savvy then use the id to your advantage. This will also boost your SEO. I would say when it's not of use, then encode it. It only takes one developer one mistake to not check a customer id against a session and you expose your entire customer base.

But of course, your unit tests should catch that!

2012-04-05 22:42
by Brett Jones
That is another thing to think about -- either informative and legible or temporary and meaningless is good, but I'm continuing to feel that inherited from the DB just because is not; any suggestions for how to actually implement the mapping for either kind? Just a column in the DB for the user-friendly, I would thin - nik.shornikov 2012-04-06 19:08
Oh i see. You mean the mapping of smashing-pumpkins to 1456789. I think it would have to be another column in the db. But most of the mvc examples I see are just using identity ints all over the place. The problem is that 1456789 is autogenerated guaranteed unique. Anything you try to do with one of the other meaningful fields may not be unique, and if it's not unique it's no good to try to use it for a query. Unless you do something like hotmail, smashing-pumpkins, smashing-pumpkins8973232, etc - Brian White 2012-04-06 22:14


0

While you will find some people who say that IDs are just an implementation detail, in most systems you need a way of uniquely identifying a domain entity, and most likely you will generate an ID for that identifier. The fact that the ID is generated by the database is an implementation detail; but once it has been generated it becomes an attribute of the domain entity, and it is therefore perfectly reasonable to use it wherever you need to reference the entity.

2012-04-05 19:46
by David Nelson
Ads