Public APIs vs Private API
I have an API endpoint https://api.example.com/api/v1/example/trending.
The API is intended for Android and iOS apps. Currently, if anyone browses the above URL they will get the public results because it is used for the mobile splash screen.
From the moment you publish an app that calls an API, that API is public, even if you have done your best to keep it private, like not having public docs for it anywhere, and/or having it behind authentication mechanisms, and this is because all the attackers needs is to perform a MitM attack in order to enumerate all the API endpoints and how they are used by the mobile app.
It seems that you have an API that is not behind any form of authentication. By other words your API seems to not try to distinguish between who vs what is calling it.
So, I would like to first clear a misconception that usually I find among developers of any seniority, that is about the difference between who and what is accessing an API server.
The Difference Between WHO and WHAT is Accessing the API Server
I wrote a series of articles around API and Mobile security, and in the article Why Does Your Mobile App Need An Api Key? you can read in detail the difference between who and what is accessing your API server, but I will extract here the main takes from it:
The what is the thing making the request to the API server. Is it really a genuine instance of your mobile app, or is it a bot, an automated script or an attacker manually poking around your API server with a tool like Postman?
The who is the user of the mobile app that we can authenticate, authorize and identify in several ways, like using OpenID Connect or OAUTH2 flows.
You can think about the who as the user your API server will be able to Authenticate and Authorize access to the data, and think about the what as the software making that request in behalf of the user.
So, by your description your API doesn't seem to try to identify neither the who or the what, but at least you can modify it to identify what is doing the request to it in order to lock down your API server to only serve requests from genuine and untampered instances of your mobile app.
Possible Solutions
How can we restrict the results to be only available on the mobile app?
To lockdown your API server with your mobile app you can start by using an identifier in the mobile app, like an API key, as I wrote about in the article I already linked above, and where I wrote:
When Should I Use an API Key in a Mobile App?
I hope that by now that you understand the difference between who and what is accessing your API and the difference between a public and a supposed private API, thus being aware that an API server needs a way to know what it is serving the requests to, even before it is able to know who is making those requests.
It should now be clear that every time you build a mobile app that communicates with an API server, a secret must be used to identify it, and this secret is usually named by developers as an API key.
But now you have another challenge, and not an easy one, how do you will secure this API key from being extracted, and from the same article I will quote:
Is it Possible to Secure The API Key in a Mobile App?
This is a tricky one and the reply is NO and YES…
Well, it is NO because any static secret stored in the source code of a mobile app can be reverse engineered by using tools that decompile the binary of the mobile app, leaving it exposed to human eyes and tools like grep
, but you can even try to use the strings
tool to perform a lookup into a binary without the need to decompile it.
Let’s imagine that you are an advanced developer and went the extra mile to protect the API key and calculate it dynamically at run-time. Your effort is appreciated and will put off most of the script kiddies, but will not take away the hackers, that will use introspection frameworks like xPosed and Frida in conjunction with the already decompiled code to understand how and where the API key is generated at run-time in order to intercept and extract it. A better way exists though, using a proxy between the device that the hacker controls and the API server is a fast and easy way to grab an API key generated at run-time.
So, I just quote why is not possible to secure the API key, but I don't quote the bit about how it's possible to secure it, because first I want to point you out to how you can reverse engineer your mobile app and how to do a MitM attack.
To learn how to reverse engineer a mobile and at same time how to hide secrets in a mobile app, that are hard to extract with static binary analysis, I recommend you to read my article How to Extract an API key from a Mobile App with Static Binary Analysis:
The range of open source tools available for reverse engineering is huge, and we really can't scratch the surface of this topic in this article, but instead we will focus in using the Mobile Security Framework(MobSF) to demonstrate how to reverse engineer the APK of our mobile app. MobSF is a collection of open source tools that present their results in an attractive dashboard, but the same tools used under the hood within MobSF and elsewhere can be used individually to achieve the same results.
So, if you are not able to extract the API key, because it's hidden in native C code, then you do a MitM attack as I show in my article
Steal that Api Key with a Man in the Middle Attack:
In order to help to demonstrate how to steal an API key, I have built and released in Github the Currency Converter Demo app for Android, which uses the same JNI/NDK technique we used in the earlier Android Hide Secrets app to hide the API key.
So, in this article you will learn how to setup and run a MitM attack to intercept https traffic in a mobile device under your control, so that you can steal the API key. Finally, you will see at a high level how MitM attacks can be mitigated.
By now you may be wondering that no matter what method is used to hide the API key, you are doomed to fail your mission to allow the API server to identify what is doing the request, but you can still do a lot more, and to learn about what more can be done I recommend you to read this answer I gave to the question How to secure an API REST for mobile app?, especially the sections Hardening and Shielding the Mobile App, Securing the API Server and A Possible Better Solution.
The above answer will give you an overview about mobile app hardening, basic and advance API security defenses, and also would introduce you to a possible better solution by using the Mobile App Attestation concept.
In a nutshell the mobile app attestation will allow your API server to identify what is doing the request, therefore it bill be able to distinguish requests from genuine and untampered instances of your mobile app from requests made by bots, scripts, cURL, Postman, or any other tool.
Do You Want To Go The Extra Mile?
In any response to a security question I always like to reference the excellent work from the OWASP foundation.
For APIS
OWASP API Security Top 10
The OWASP API Security Project seeks to provide value to software developers and security assessors by underscoring the potential risks in insecure APIs, and illustrating how these risks may be mitigated. In order to facilitate this goal, the OWASP API Security Project will create and maintain a Top 10 API Security Risks document, as well as a documentation portal for best practices when creating or assessing APIs.
For Mobile Apps
OWASP Mobile Security Project - Top 10 risks
The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.
OWASP - Mobile Security Testing Guide:
The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.