Avoiding exposing identifier details to your users
A sadly common place “attack” on applications is called “Web Parameter Tampering”. This is the case where you have a URL such as this:
And your users “hack” you using:
And get access to another users records.
As an aside, that might actually be considered to be hacking, legally speaking. Which make me want to smash my head on the keyboard a few time.
Obviously, you need to run your security validation on parameters, but there are other reasons to want to avoid to expose the raw identifiers to the user. If you are using the a incrementing counter of some kind, creating two values might cause you to leak the rate in which your data change. For example, a competitor might want to create an order once a week and track the number of the order. That will give you a good indications of how many orders there have been in that time frame.
Finally, there are other data leakage issues that you want to might want to take into account. For example, “users/321” means that you are likely to be using RavenDB while “users/4383-B” means that you are using RavenDB 4.0 or higher and “607d1f85bcf86cd799439011” means that you are using MongoDB.
A common reaction to this is to switch your ids to use guids. I hate that option, it means that you are entering very unfriendly territory for the application. Guids convey no information to the developers working with the system and they are hard to work with, from a humane point of view. They are also less nice for the database systemto work with.
A better alternative is to simply mask the information when it leaves your system. Here is the code to do so:
You can see that I’m actually using AES encryption to hide the data, and then encoding it in the Bitcoin format.
That means that an identifier such as "users/1123" will result in output such as this:
The length of the identifier is larger, but not overly so and the id is even URL safe . In addition to hiding the identifier itself, we also ensure that the users cannot muck about in the value. Any change to the value will result in an error to unmask it.