Limit Vulnerability For Public API

Suppose you’re making a public-facing full stack application that doesn’t require user logins. This application also references some relational resources via a REST API that you’re designing.

This situation presents an interesting problem in that the API must be public, and anyone can curl it. So anyone can potentially get, update, or delete resources she/he shouldn’t have access to through the front-end interface. So how do you prevent this?

One solution is to not expose the database primary key in the URL as resource identifiers, which is typically numerical and auto-incremented. The numerical and auto-incrementing nature makes it extremely easy to guess similar resources.

For example, an endpoint that returns a resource data with an identifier of dataId can look like this:

/api/data/:dataId

If dataId is simply the database primary key, and I somehow know that /api/data/872972 exists, then I can just as easily try /api/data/872973 or any other number to access a resource that developers did not intend for me to have access to.

We can obfusicate the primary key via some sort of hashed string, url_hash, store the url_hash in the database for look up, and serve the resource identifier via this url_hash. So it’s important that this url_hash is unique and have no collisions, or have very low likelihood of collision. It’s also imperative for the purpose of this application that the resulting url_hash has sufficient character length to make it impossible to randomly guess a correct identifier.

A UUID seems very appropriate here. But do keep in mind that UUIDs to savy programmers are still quite easily guessable. Alternatively, what other hashing methods can we use? Anything else we can do? Maybe choose a different hashing method: SHA512, etc. Maybe also salt the hash.

The key is that if you make the resource ID difficult to guess, then it is at least one layer of deterrent from malicious users. And it’s not difficult to make something that’s near impossible to guess. A 32 character hex key provides 3.4 * 10^38 possible combinations.

Back