Reputation: 19717
In my web application I use primary keys to generate hyperlinks in order to navigate to different pages:
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
@Html.ActionLink("Details", "Details", new { id = item.Id }) |
@Html.ActionLink("Delete", "Delete", new { id = item.Id })
</td>
I was wondering if this code is a security concern. Is it advisable to expose primary keys in ASP.NET MVC views? If this is the case what are the alternatives? Should I encrypt the IDs in my viewmodels or should I create a mapping table between public and private keys?
I appreciate your advice
Upvotes: 5
Views: 1854
Reputation: 10201
What exactly do you mean by "primary key" in this context? That term is a database term. In your browser, it's just an identifier. What difference does it make if that identifier is stored in a column with a primary key constraint on it, or a column with a unique index on it, with or without some reversible transformation on its value before storing?
There is obviously no direct risk in exposing an identifier.
But there are risks associated with identifiers, that may have to be mitigated.
For example, you must ensure that knowledge of the identifier does not imply full access to the identified resource. You do that by properly authenticating and authorizing all resource access. (Update: some other answers have suggested that you may do that by making identifiers hard to guess, e.g. through encryption or signing. That is nonsense of course. You protect a resource by protecting it, not by trying to hide it.)
In some cases, the value of an identifier may carry information that you do not want to expose. For example, if you number your "orders" sequentially, and a user sees they have order number 17, they know how many orders you have received in the past. That may be competitive information that you do not want to expose. Also, if identifiers are sequential, they contain information about when the identifier was created, relative to other identifiers. That may be confidential as well.
So the question is not really "can I expose identifiers", but rather "how should I generate identifiers in such a way that no confidential information is exposed through them".
Well, if the number of identified resources is not confidential, just use a sequence (e.g. as generated by an identity column). If you want the identifier to be meaningless, use a cryptographic random number generator to generate them.
Upvotes: 1
Reputation: 462
I believe that there is no risk to expose primary keys to the public, I think you should pay attention to where vulnerabilities start. As long as your generated urls are tamper-free and you are certain about deciding a given url is generated within your application and no-man-in-the-middle, all go smoothly. To do that, I invariably use a hash-styled mechanisms and provide an extra parameter to my urls made up from primary key and something else to check for tamper.
Upvotes: 0
Reputation: 9289
Their is no issue to public the ID of item in Web-applications.
If your code CRUD ajax request take ID parameter and process on it then a user can call many ajax request within firebug very easily. If you didn't permit too much to a guest user then it would not be a big problem.
Security doesn't means anything in this context. You just remember that all your code are safe from XSS.
expose of primary ID make it easier for people to remember or hack the url and go to next one (item or page). The only thing you need to care that always check security (XSS for this question)
Upvotes: 0
Reputation: 35905
Generally, there is no point of encrypting item id, because this is not considered (in most business domains) confidential information. Unless your domain specifically requires to keep id private - don't do this. Keep it simple, stupid.
There is no security concern associated with this.
Upvotes: 4
Reputation: 75
Gone are the days when people seeing you primary or surrogate keys were able to hack down the database. Now sql injections and backdoor concept are subsided. 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 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.
Upvotes: 9