views:

157

answers:

4

Question

Should autoincremented identity columns have a non-default seed/increment when used in a RESTful web application?

Background

I'm working on my first ASP.NET MVC application and trying to keep my urls RESTful. There is no separate administrative web site for the application. I use attributes to control who can access what parts of the site and what menu items are visible to the current user based on their roles in the system. I (mostly) follow the ActiveRecord DB pattern and use synthetic ids for my tables, including the user table, with the ids being autogenerated identity columns.

It occurred to me this morning that there is a subtle security risk to using default seeds for identity columns in a RESTful application. If you assume that administrative ids, particularly the most powerful ones, are typically created first in an application, then it follows that they will be the lowest numbered ids in the system. While not actually opening a hole in the application, using default values for the seed/increment could make it easier for a cracker to attack a high value target simply by targeting low numbered ids using RESTful actions (such as ChangePassword -- which is one of the out-of-the-box actions in the ASP.NET MVC site template).

Should I add setting a non-default seed to, at least, my users table to my arsenal of security best practices? Is the effect of doing this worth it? Or am I being too paranoid? As a related question, should I be changing the out-of-the-box template names for account-related actions.

+3  A: 

My advice is to use GUIDs instead of autoincrementing IDs. That gets rid of the "guessing game" altogether.

Lucero
Agree with this. There are several advantages. You don't have to wait to hit the DB to get the unique ID -- you can generate it and then queue it if you need to. You can base 64 encode these and pass them around as 25 character strings that you could use as query parameters in a URL.
JohnOpincar
Thank you John. And there are even more advantages, such as the ability to use those IDs for offline work or synchronization etc. - GUID PKs have many advantages (and sume disadvantages, such as being 4 times as large as a normal int or hard to remember for debugging and testing).
Lucero
I'd wager most DB's could handle the 4 time size increase. I would expect that except for the largest of DB's this wouldn't have a major impact, given how cheap disk space and memory are now adays.
JoshBerke
Josh, that's true, however, there are some performance impacts beyond space and memory. 4 times the size means 4 times as large index (for non-clustered indexes), 4 times as many pages to be loaded (due to fixed page size) etc., so that there is in fact some performance impact especially for huge data collections. That said, I like GUIDs very much and I have almost always been using GUIDs with no performance issues in general, but keeping this in mind is a good idea I think.
Lucero
A: 

I have been very skepticle of using Guid's; however, as Lucerno points out it does help minimize the guessing game depending on how the Guid is generated and used. Guids generated using sequential from SQL Server, would not prevent the guessing game for example.

Guids are also very handy if your have a domain model and your using an ORM like nHibernate or even rolling your own. As it simplifies greatly the complexity of inserting the backreferences since all objects can be given their id's early on.

With that said if your Id's are included in the URL they should be treated as very public data. Even over HTTPS a devious attack could get the whole URL. If your page requests any third party content such as Google analytics for example, the url query string and all, is sent to the third party as the referer for example.

JoshBerke
A: 

Keep the logged in user on the session on the server side rather than passing it to the client - that way the client can never alter the user id in a malicious query.

JeeBee
But what if I want an administrator to be able to use the same action to change the password on behalf of a user?
tvanfosson
I'd put the other user object on the session as well for that action, and maybe have a hidden field in the change password form like "modifyOther" = "Y", which the server can check to decide on what action to take.
JeeBee
A: 

I've decided, for now, that I'll address the risk by changing the default seed for autoincrement columns. This isn't hard and won't change the character of the application or the ActiveRecord pattern. Since these columns are also used for foreign key relationships I want to keep them integers to make the indexes more efficient.

I'm not planning on change the default actions unless a different verb makes more sense. Having the interface be intuitive is more important than hiding the action behind an obscure name.

tvanfosson