REST API: Security through obscurity

Making a REST API more secure.

Today, creating a REST API is super easy. There are tons of tutorials who will help you build and plan your project. This article won’t cover on how you can make the best of the best APIs in town, but rather how to make your API — however it may be built — more secure.

Keep vital data inside

One point I always come across while consuming APIs, is the fact that most of them, almost willingly, share their internal data with you. Which internal data you mean? The ID of a resource.

In most cases this ID is an autoincrement primary key of an entry in your database. Which is totally fine as long as you keep using it inside your own domain.

If you simply use your primary IDs for your resource and expose them to the user, it is easy for an attacker to guess every other resource, just by increasing the number.

Obfuscate!

Before we begin on how to actually do this — what is obfuscation? The dictionary describes it as follows:

The act or an instance of making something obscure, dark, or difficult understand

Simply put: Take the obvious and make something new out of it in a way only you understand. If the attacker does not know the “how”, it is harder to guess what the next number in the chain might be.

Whatever we are doing in this regard — it is still just obscurity, so somebody will be able to break it for sure.¹

As an example we take the video URL of YouTube. This also uses some kind of ID obfuscation: /watch?v=1gQfGZTpThw . While the URL itself is super simple, behind the scene this alphanumerical “hash” probably simply maps into some kind of numeric ID.

This is all fine and good, but how to use this?

Lets start with a simply assumption: You have a simple REST API where a user can call an User endpoint to retrieve some data from it. This might look something like this:

With this image you see the user simply calls an endpoint with the numeric ID of an user, which then simply gets passed into the database to retrieve the data.

Always sanitize external data! Especially if you pass them into your database!

Now an attacker simply can increase the number in the URL and retrieve any dataset that might exist. This is not good for you, your cat— no its not good.

Now we can change the whole database to use hashed IDs instead of numbers and change the whole application to use those new IDs instead of our old ones — but there is an easier way.

We only obfuscate outgoing IDs and clarify incoming ones.

Taking the diagram above we make a small change and we get this:

As we can see, the user now has to provide an obfuscated ID into our application. Inside our application we can still use the numeric ID we always had. So no big change here required.

Choosing the right tools

There are many libraries out there which can help you create such “hashes”. One of them that I am using, which is written in different languages, is called Hashids² by Ivan Akimov and maintainers.

While I a mostly working with Zend-Expessive I have also written a small Middleware and Helpers³ which utilize this library to decode incoming IDs and encode outgoing ones.



Thanks for reading the article. If you liked it leave some 👏 and share the hell out of it. If you have question you can hit me up right here in the comments below or follow me on Twitter @icanhazstring.