Hide direct object references to increase application security

Whenever a user is about to access certain data within your web application you want to make sure, he has only access his data, not other user's data. A critical measure to prevent vulnerabilities here, is to implement tight authorization checks on a functional level. This is very essential to security and should not be missed. Anyhow, you can increase security further with a fairly simple additional measure.

User controlled keys

To access a specific object, like a database record or a file on disk, a user is required to pass a key - e.g. the databases record's ID. A request transmitting a key as URL parameter might look light this:

https://myapp.tld/invoice/10001

The passed key parameter is called a user controlled key - because a user has control and can change a request's key. In most cases this happens in the background. The user is not supposed to enter the key manually. But be aware: if a user looks behind the curtain - or the network activities - to understand how you are delivering the key from client to server, a user may create similar requests on his own and alters the key.

https://myapp.tld/invoice/10002
https://myapp.tld/invoice/10003
https://myapp.tld/invoice/10004

By testing out various possible keys, he may gain access to other user's data, if authorization checks fail. Let's face it: programmers do make errors and a security measure might fail. Therefore it is advisable to establish multiple levels of different security measures to secure a possible attack vector.

This attack scenario of insecure direct object references is described by the OWASP (Open Web Application Security Project) and ranked as a Top 10 security issue.

Use indirections

There is a fairly simple method to increase security dramatically by not using direct object references. If a user can hot have a peek at the keys, or direct references, to his data, he may not be able to guess other user's keys.

So, instead of using a direct reference as key, use an indirect references that is not guessable. You call this concept indirections.

So, don't to this:

https://myapp.tld/invoice/10001

Instead do this:

https://myapp.tld/invoice/k7GDLt&%nkdnjnKH6767bjhhasd5VssJasd5a

Within your application logic you need to establish a mapping. A list of obscured, indirect references given to the user, that maps to direct references kept secure on your server.

If you are pro, you are going to create the indirect references individual for every user an store them in his session data.

The concept of indirections is defined in the OWASP ESAPI (Enterprise Security API) under the name access reference map. A helpful resource to build this is the documentation of the Java ESAPI implementation, where you can find an interface for the an access reference map