Drazen Golic

Securing server APIs for mobile apps without user registration

Contents:

The Problem

Let’s suppose you have to create an API for your mobile app, and the app must be fully functional without asking the users to register (first). This could be for various reasons, for example:

Yet, you still want to make your APIs exclusive to your app in order to prevent misuse of your data and the resources that you’re paying for.

There are a couple of options being used in the wild, but all of them are flawed:

  1. Fully open API - we already decided this is unacceptable
  2. Using a secret key shared between the app and the server - This is easy to break, as the apps are relatively easy to decompile and have all the string constants extracted from them. And if the key gets compromised, you’ll have to update both the app and the server, until the new key gets compromised just as the previous one
  3. Splitting the key to different parts of the app, or using some simplistic algorithm to generate one - This isn’t much harder to discover than a stored string, so it’s just as futile as the previous option

Now, even if you require users to register, someone savvy enough to extract their legit access token to your APIs can still misuse them if you don’t have a mechanism in place to limit their usage, such as request limits and throttling. You can limit your API usage based on the IP address (and you should always do that!), but this limitation can be easily avoided by using different proxy servers, or by having access to a fleet of hosts with different IP addresses.

The Solution

So, you still need some form of registration. But instead of users, you could register a device running your app. But how do you make sure that it’s your app that is asking to register, and not something else? With something unique to your app: push notifications.

Disclaimer: there are no bullet-proof solutions, and neither it’s this one. However, it’s good enough to keep those less tech-savvy and less motivated at bay, while enabling you to apply different security strategies just like for APIs with user authentication.

Without further ado, here is a full sequence diagram of the device registration workflow:

Device registration worflow

Device registration worflow

TL;DR: the app is asking the server to send it a registration URL via push data message, that is also encrypted with a public key generated by the app.

After the registration is complete, you can continue with the usual refresh token flow to access the APIs.

Some important notes about the challenges:

Generated device ID could be an UUID, or anything similar. And if delivering push notifications is a regular feature of the app, it’s a good idea to store the ID with the push service registration token together somewhere (effectively registering a device account) so you could easily update the token on the server when the app receives a new one from the push service. Note that you don’t need to ask users for permission to retreive data messages without displaying a notification.

Having the device ID in the access and refresh tokens will allow you to limit usage per device, and in case of a detected misbehavior, even deny refreshing the access token (thus shutting down the device account either temporary or permanently). Expiration time for the new access tokens should be reasonably short.

Usage in The Real World™

While I have a PoC project with this design, it’s not ready for production yet. But if you like the idea and decide to use it in production yourself, please do give me a shout on how it went over any channel where I’m present! Maybe there are no comments on this website, but I’d be happy to publish any real world experiences (with your permission) as a part of this article.

#Mobile   #API   #Security