I often come across web applications that expose internal database primary keys through forms like select boxes. And occasionally I see javascript matching against an int or guid magic value that switches the logic.
Is is a best practice to avoid leaking all internal identifiers of rows in your web application to prevent outsiders from understanding too much of your system and possibly using it to exploit your system. If so what is the best way to solve this problem?
Should you expose some other value to the web app that can be translated back to the primary key?
Thanks
Edit
In a perfect world your application would be 100% secure so it wouldn't matter if you obscured things. Obviously that's not the case so should we error on the side of caution and not expose this information?
Some have pointed out that Stackoverflow is probably exposing a key in the Url which is probably fine. However are considerations different for Enterprise Applications?
The answer is, "it depends". For most user communities, exposing the internal key will result in the key becoming used as a natural key. This can, and usually does, result in some confusion when the one-to-one mapping between the internal key and the subject of the table row breaks down.
6. Which one of the following cannot be taken as a primary key? Explanation: Street is the only attribute which can occur more than once.
I disagree with the stance that exposing primary keys is a problem. It can be a problem if you make them visible to users because them they are given meaning outside the system, which is usually what you're trying to avoid.
However to use IDs as the value for combo box list items? Go for it I say. What's the point in doing a translation to and from some intermediate value? You may not have a unique key to use. Such a translation introduces more potential for bugs.
Just don't neglect security.
If say you present the user with 6 items (ID 1 to 6), never assume you'll only get those values back from the user. Someone could try and breach security by sending back ID 7 so you still have to verify that what you get back is allowed.
But avoiding that entirely? No way. No need.
As a comment on another answer says, look at the URL here. That includes what no doubt is the primary key for the question in the SO database. It's entirely fine to expose keys for technical uses.
Also, if you do use some surrogate value instead, that's not necessarily more secure.
Yes, exposing keys is information that can be used as an attack. Especially if they are predictable.
Use a different key/column if you think the information is sensitive.
For example to avoid showing how may users you have, consider:
site.com/user/123 vs site.com/user/username
Yes to all your questions. I agree with your assertions that you should "expose some other value to the web app that can be translated back to the primary key"
You can open yourself up to potential problems otherwise.
Edit
Regarding the comment that "there is no reason to take the penalty hit for trivial keys. Look in your browser's URL right now, I bet you see a key!".
I understand what you're saying and, yes, I do see the key in the SO URL and agree it probably does refer to a database PK. I concede in instances like this it's probably OK if there's not a better alternative.
I'd still prefer to expose something other than a PK - something with semantic value. The title of the question is also in the URL, but since this would be hard to verify as unique (or pass between users verbally) it can't be used reliably on it's own.
When looking at the "tag" URLs however (i.e. https://stackoverflow.com/questions/tagged/java+j2ee), the PKs are not exposed and the tag names are used instead. Personally, I prefer that approach and would strive for that.
I also wanted to add that the data a PK points at can sometimes change with time. I've worked on a system where a table was filled with info from an offline process - i.e. monthly statistics where the DB table contents dropped at the end of the month and was repopulated with new data.
If the data is added to the db in a different order, the PKs for specific data points would change, and any saved bookmarks from a previous month to that data would now point at a different set of data.
This is one instance where exposing a PK would "break" an app unrelated to the security of the app. Not so with a generated key.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With