Web Security – Is Obfuscating Public-Facing Database IDs Best Practice?

Securityweb-applications

I've heard people lecture here and there on the internet that it's best practice to obscure public facing database ids in web applications. I suppose they mainly mean in forms and in urls, but I've never read anything more than a mouthful on the subject.

EDIT: Of course, now that I ask this, I find some resources on the subject:

These links satisfied some of my curiosity, but the SO posts don't have many votes and aren't necessarily centered around the topic in this context so I'm not sure what to make of it, and some of them claim that the third link is bogus. I'll leave the rest of my post intact:


I understand the differences between obscurity and security, as well as how the two can work together, but I can't imagine why this would be necessary.

Is there any truth to this, is it just paranoia, or is it just totally bogus altogether?

I can think of ways to do it, but of course it adds a lot of complexity to the application code. Under what circumstances would this be useful? If this is something people frequently do, how is it usually deployed? Hashing the identifiers? Something else? It seems like a lot of work for not much extra security. I'm not looking for real solutions, I just want to get an idea of how/why people would do this in the real world.

Is this really considered a "best practice" or is it merely a micro-optimization of little value?

NOTE: I think a few folks might have gotten the wrong idea: I'm not suggesting that difficult-to-guess ids would be the only security mechanism, obviously there would have be the usual access checks. Let's assume those are in place, and that simply knowing the id or hashed id of a record is not enough to grant access.

Best Answer

I don't think it's that important, but there are some scenarios when it could matter depending on other decisions you make.

For example, if you were to expose an order ID that's generated sequentially, and you had a social engineering attack with someone calling customer support and saying "hey, I just spent $2000 on a new computer and you guys sent me some other guy's order for a $15 cable, now I'm out $2000" you could spend a lot of time trying to vet the issue before you either conclude it's bogus or you send the faker a new computer.

There are similar, less sophisticated, but embarrassing variations on the theme; if a bad guy increments an order ID an emailed link to a receipt, and if no additional validations are made to verify that the person who clicked on the link has the right to view the order ID, suddenly you're unwittingly exposing private customer information to the wrong person.

In such cases, if the numbers are non-sequential the exposure is slightly mitigated because guessing is less likely to yield interesting results. On the other hand, now you need a convenient way to reference an order ID in customer support interactions that won't result in long back-and-forth conversations with telephone-based customer interactions while your rep tries to distinguish between B, P D and T in order number BPT2015D.

I'd say it's a stretch to call this obfuscation a "best practice", but in certain scenarios, it can reduce the ease of exploiting another weakness in your validation or authorization code. On the other hand, it doesn't really matter whether someone knows you wrote blog post #1 or #2559. If the ID isn't valuable information, even with additional knowledge, then the argument that obfuscating it is a best practice holds less weight.

There's a second potential argument, which is that your database identifier may wed you to a particular database implementation (or instance), and when your company gets bought out or picks up a competitor and now you have to merge two legacy systems, or the CEO goes out drinking with the rep from DynoCoreBase and they decide that you will now move all your data to DynoCoreBase version 13h and it wants all the primary keys to be guids, and you have to create some sort of mapping layer to translate old IDs to new IDs so that old URLs don't break, but whether these scenarios matter to you depend far more on the nature of your business (and the customer involvement with those IDs) than on any general best practice.

Related Topic