There is an increasing realization that eradicating vulnerabilities from your APIs is only half of what you need to win the battle to secure your backend services from the unwanted attention of bad actors. In this article we’ll explore what you need to do in addition to vulnerability hunting in order to protect your business from fraud, data breaches, account takeover, fake account creation, spamming, data scraping and service takedown.
Finding flaws in your APIs
The OWASP API Security Project is an excellent example of the technical community coming together to hammer out a set of best security practices related to APIs. Flaws or vulnerabilities in your APIs are bugs in the design or implementation which hackers can use to circumvent your security mechanisms and access your backend services and resources.
Imagine a situation where your API is expecting a unique identifier alongside regular user credentials in order to direct a transaction. The unique identifier might be a bank account, a patient ID or any kind of reference code. All good so far. But what happens if I am a bad guy and I decide to modify the unique identifier to something else; I could give it a random value or I could simply increment it by 1 each time. Is the system smart enough not to allow me to access data which is not associated with that user? If not then there is a bug in the API design.
Now consider if I present another transaction where the unique identifier field is empty, or filled with garbage. Does the system crash, or worse, does it return with the data associated with every possible unique identifier? If either of these scenarios occurs then you have a bug in your API implementation.
The Top 10 recommendations cover many more scenarios like the ones above and they form the basis of many enterprises’ internal security policies for API development and deployment. Further, they are often given to pentesters as the blueprint to direct their activities. In such enterprises, proof that an API is free from the issues found in the Top 10 list is often equated with an API that can be deployed in production, with confidence that nothing bad will happen.
If only life were that simple.
What else could go wrong?
Unfortunately, quite a lot. The thing is, exploiting vulnerabilities is only one approach to gaining unauthorized access to an API. The other way is to set up a script which impersonates ‘good’ API requests.
Imagine a script which has within it valid user credentials such as usernames/passwords (or user authentication tokens) and valid API credentials such as API keys. Imagine also that this script generates correctly formed API requests using these credentials. Could your API endpoint security tell the difference between this scripted traffic and genuine API requests? My guess is probably not.
If the script operates at high frequency then any rate limiting you have in place might trigger, or if the script deviates from ‘normal’ user behavior then you might detect that as ‘suspicious’ activity but most likely you won’t notice it. Automated abuse is easily the most common attack vector against APIs today, for the simple reason that it is effective and it is easy to do.
The modern hacker is smart and sophisticated, and certainly doesn’t do work that is not necessary. If he/she is going to go to the trouble of studying and reverse engineering your API and extracting any available credentials for reuse, the first API access attempt they try will involve impersonating genuine API traffic. Think about it – why would they go to the trouble of searching for API vulnerabilities and figuring out how to exploit them when just building a script to mimic good traffic can give them all the access they need?
The fact that distinguishing between genuine and scripted traffic is so difficult amplifies the risks associated with this attack. Most enterprises have no idea how much API abuse they are suffering through this route, and the potential dangers which are in play. Automated API threats like this can be used to present valid user credentials to an API endpoint which could result in an existing account being taken over, resulting in a data breach.
Automated attacks against APIs are a whole other class of exploits which need to be considered alongside the OWASP Top 10 previously mentioned. In fact the OWASP organization created a project to look at Automated Threats To Web Applications, illustrating the fact that abuse through automated traffic is a different threat class from exploitation of vulnerabilities.
Practical steps all enterprises can take
What steps can be taken to improve the situation and protect APIs against unauthorized use by scripts? Let’s look at 3 different API situations and how they can be secured, starting with the easiest.
A server to server API connection is relatively simple to protect because both ends can be considered trustworthy. A traditional public/private key pair approach over an encrypted channel will work for this situation.
Next, let’s turn to APIs connecting web pages to backend servers. Obviously we need to be suspicious about the web page and whether it is what it says it is because we don’t control it. The good news is that web pages usually don’t contain too much capability and tend only to download data from enterprise servers which the page immediately needs. Although this naturally limits the size of the risk, it is still important to take steps to protect against scripted traffic. Fortunately there are a number of solutions available which can provide feedback on the veracity and reputation of a web page. Google’s reCAPTCHA v3 is a good example of an approach which gives good guidance on when to trust website traffic and which is also invisible to genuine users.
Finally, to the most difficult APIs to protect; those which service your mobile apps. Mobile apps contain such a lot of business logic that they are powered by APIs with very rich features, capable of accessing large sets of diverse data from your backend servers.
Since anyone can download and reverse engineer your mobile app then you absolutely cannot trust any API request containing credentials which are stored in the app, such as API keys, or which have relatively long lifetimes and pass through the app, such as user authentication tokens. It is essential, in addition to checking API keys and/or user authentication tokens, that you verify that each API request comes from a genuine instance of your mobile app and that the mobile app was not running in a compromised runtime environment.
To understand in detail what you need to do to protect this most difficult of channels, namely your APIs which service your mobile apps, take a look at my recent talk at APIDays London. It includes a 5 step plan which you can follow and quickly raise significantly the level of protection against all forms of automated API traffic. It will also allow you to get a handle on the scale of your problem because you will be able to see exactly how much abuse of your APIs is going on.
Once you realize that this approach allows you to distinguish between traffic coming from your genuine app instances and traffic coming from automated scripts, you’ll also realize that traffic coming from modified, cloned or repackaged apps will also be blocked because these are not genuine app instances.
And there’s even a free lunch too!
At the start of this article we noted that APIs may have design or implementation vulnerabilities within them and that these vulnerabilities may be exploited by bad actors. The vast majority of the methods used for these exploits are based on scripts. If you want to try hundreds of different unique identifiers to see what data you get back, you wouldn’t do that through the enterprise website or mobile app, would you? Of course not – instead you would build a script to try all of the different combinations of the variable and report back the results when all the permutations had been tried.
But wait, this is exactly the same approach as the bad guys who impersonate valid API traffic use isn’t it? So if you block unauthorized use of your APIs by scripts then you will also stop the hackers who are looking for vulnerabilities in your APIs.
Put another way, blocking fake API traffic from scripts protects you from impersonation attacks and, as a free lunch, also protects you from any attempts to exploit vulnerabilities which you may or may not know about in your APIs. So, why wouldn’t you block such scripted traffic?