Introduce an API Key Proxy to Improve Mobile Security , , ] Pictured Above - UGC 12591: The Fastest Rotating Galaxy Known [Image Credit: NASA ESA Hubble Editor's note: This post was originally published in May 2017 and has been revamped and updated for accuracy and comprehensiveness. The latest update was in September 2022. API keys and other are a common source of mobile insecurity. You can . secrets poorly hidden inside mobile apps do much better In this tutorial, you will work with a simple Android mobile app which uses an API key to access the . An API Reverse Proxy introduced between your mobile app and the NASA picture service will remove the need for storing and protecting the API key on the mobile app itself. In addition to improved , this approach offers some benefits in manageability and scalability. Alternatively, you may choose the approach discussed in the article which doesn’t require any API backend work to be done - a significant positive if you don’t have a backend team immediately available and need a solution ASAP. NASA picture of the day service API security Runtime Secrets Protection During the tutorial, you will modify an Android mobile app and a NodeJS API reverse proxy server. For demonstration purposes, both the Android mobile app and the API reverse proxy server can be run together on a single laptop, but to make it easier for you to follow along we will provide an online API Reverse Proxy server. I assume that you have some very basic familiarity with Android and can read Java and Javascript. All code is provided, so it should be possible to follow along even if you have limited experience in these environments. THE ASTROPIKS MOBILE APP The AstroPiks Android mobile app is relatively simple with only two main screens. The initial screen displays a gallery of recent NASA pictures of the day. Clicking on an image brings up a detailed screen containing the full image and its description. The mobile app uses to retrieve images and descriptions. To access the service, the API requires a registered API key which will be initially stored in the mobile app. NASA's picture of the day API WHY DO WE NEED AN API REVERSE PROXY? Mobile Apps of any complexity will make extensive use of multiple 3rd party services via their public APIs which means handling and safeguarding many secret API keys. Secrets are supposed to be kept secret. Unfortunately, for a secret held on a mobile app, it's not a question of if it will be stolen but when it will be stolen and how much effort it will take. By introducing an API reverse proxy server between the mobile app and its 3rd party services, we can remove the API keys from an insecure mobile app and place them on a more secure API reverse proxy server. We’ll also add a mobile app attestation service to establish trust between the mobile app and the new API reverse proxy server. This approach is discussed in detail in the . Mobile API Security articles We'll use the NASA service as an example of an API which would be typically called from a mobile app. We've added an extra hop between the mobile app and 3rd party service, but it does offer significant benefits. Since we've removed the secret from the mobile app, it's no longer there to be stolen. If the secret is somehow compromised, it can be replaced in the API reverse proxy server with a fresh secret. From a manageability standpoint, since the secret is no longer on the mobile app, the decision can be made to improve security without requiring any change to the installed base of mobile apps. The API reverse proxy server itself is which brings load balancing, failure recovery, and other scalability benefits. By establishing trust between the mobile app and the API reverse proxy server, the mobile app attestation service offers a quick rejection filter to drop invalid traffic before burdening the actual API servers. These benefits increase as multiple API services are proxied through the same server. stateless PRELIMINARY SETUP To get started, you need to download the tutorial source code, get some keys, and ensure your development tools are in place. The tutorial should run properly on windows, mac, or linux environments. Android and NodeJS environments were chosen as sample demonstration environments. Other implementations, including iOS for the mobile app and NGINX or Go for the API reverse proxy, are also possible. 1. Git Clone the Tutorial Source Code All tutorial source code is available on Github. In a terminal or command window, change to a directory where you will store the tutorial, and clone this public git repository: git clone https: //gi thub.com /approov/ hands-on-api-proxy.git 2. Register For an Api Key from Nasa (It's Free) NASA requires a valid registration key to access their free pictures of the day service, and you can get your free NASA API Key . Once you get your API key you need to add it to the file at the root of this repo, which doesn’t exist yet. Create one by duplicating the file to and then add your Nasa API Key: on this page .env .env.example .env NASA_API_KEY =___YOUR_API_KEY_HERE___ 3. Android Studio Ensure Android Studio and its tools are installed and reasonably up to date. Android Studio Chipmunk | 2021.2.1 was the one used during this tutorial. If you need a fresh install of the Android tools, go to the to get started. Android Developers Site Initially the tutorial presumes you will be running the mobile app in an Android emulator, but you can also use an Android phone or tablet. The Android device should be running API 21 or higher. 4. Setup NodeJS The NodeJS environment is used to build and run the example API reverse proxy server. We recommend you to use our online backend for the AstroPiks mobile app, that you can find at astropiks.demo.approov.io. If you prefer you can always run the API reverse proxy yourself via the docker stack on this repo or by using NodeJS installed on the host to run it, but bear in mind that the server must be available online to complete the last step in this hands-on exercise. Docker Stack A Docker stack for NodeJS is provided and wrapped with a bash script to make it easier to be used by developers not familiar with Docker, and you can see its help to find all the available commands: ./astropiks –help If Docker is not your thing then you are free to not use it and just go with NodeJS installed directly on the host machine. NodeJS on the host machine Ensure the NodeJS environment is installed, preferably an from version 6 onward. If you need a fresh install, visit to get started. Install the ) if you want to maintain multiple node versions. LTS release NodeJS node version manager (nvm This will install NodeJS and its package manager, npm. We'll install additional package dependencies as we build the API reverse proxy. When using NodeJS from your machine then you need to copy the file at the route of the repo to .env src/proxy/nodejs/src/.env. BUILD THE INITIAL ASTROPIKS APP The initial AstroPiks mobile app communicates directly with the NASA picture of the day service. The NASA API key must be stored in the mobile app and provided with each API call. The AstroPiks mobile app is a fairly simple model-view-controller style master-detail photo gallery. The PhotoRequester class handles the initial API calls using the library, and images are downloaded using the library. The application class creates and provides the HTTP client and downloaders in a convenient place for all activities. OkHttp Picasso App Fire up Android Studio and open the AstroPiks mobile app in the working directory at . Android Studio will take a while to load library dependencies and rebuild the project. If your configuration is valid, the project should build without errors. src/client/android Before you install and run the Atropiks mobile app you need to add the Nasa API Key and URL to the file: src/client/android/local.properties api.key =__YOUR_API_KEY_HERE__ # While you are here add also: api.url =https://api.nasa.gov Now, install and run the mobile app on a real device or emulator, and you should be presented with a screen similar to this one: If you are presented with any other screen then you probably failed to follow one of the previous steps. For example, not updating the API Key in the file would show you this screen: local.properties A missing API Key is not the only cause for this screen, you can also have a typo in the API Key or in the API URL, or you can be facing network connectivity issues. To debug connectivity issues you can open a browser or use cURL and try to access the NASA service, replacing with your own key: NASA_API_KEY https://api.nasa.gov/planetary/apod?api_key=NASA_API_KEY&date=2022-07-08 For example, if you use the browser you should see this JSON response: Debug your mobile app connectivity setup and API key until you get a valid response like the one shown in the browser above. Ensure that your and are properly set in the file. api.url api.key local.properties STEALING A CLIENT'S API KEYS Your API key is used in API calls between the mobile app and the NASA server. Most production mobile apps will be calling multiple 3rd party APIs and will be holding multiple API keys. Mobile applications should always use , including certificate pinning, to secure the API communications so that your API keys cannot be easily observed. As long as an API Key is used by the mobile app, the APK contains a static representation of that key, therefore it can be reverse engineered with static binary analysis of the APK or via a MitM attack. TLS best practices Via Static Binary Analysis You can extract the API Key via static binary analysis and for that a plethora of open source tools exist, and one of the most popular ones is the , that you can see in action in this article : Mobile Security Framework(MobSF) How to Extract an API Key from a Mobile App by Static Binary Analysis Obfuscation techniques can make this more difficult, but your keys will eventually be found, and if not via this method the attacker will do it via a MitM attack. Via a MitM Attack Several Open Source tools exist to help us with a MitM attack and one of the most popular ones is the mitmproxy, that you can see in use on this article . How to MitM Attack the API of an Android App I challenge you to follow the article to replicate the steps to perform a MitM attack, and if you accept the challenge then you have two commands that are different from the linked article. First, the path to the apk is different, therefore you need to adjust it like this: adb install src/client/android/app/build/intermediates/apk/debug/app-debug.apk Second, the adb command to launch the app in the emulator is also different; adb shell am start -n "com.criticalblue.android.astropiks/com.criticalblue.android.astropiks.PhotoGalleryActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER If you follow all the steps successfully you will eventually arrive here: In the above image it is very easy to spot the API key used in the requests to the NASA API pictures of the day. The Impact of a Stolen API Key Once your API Key is discovered, it can be used to access NASA's public services. In this case, repeated calling of the NASA API by a hacker will trigger rate limits, and you will eventually be denied access as a result. But what if you are an e-commerce site? If your site is busy processing nonsense API calls, real customers will be denied access or give up because of poor responsiveness. A malicious hacker might be able to create a bunch of fake orders for merchandise or gain access to competitive information. Alternatively, a hacker could create using your API to display your inventory at a reduced site, gather orders from soon to be angry customers, and grab their credentials and credit card info in the process. a look-alike app Let's get that secret out of your app. MODIFY THE ASTROPIKS MOBILE APP TO USE THE API REVERSE PROXY We saw that secrets shipped inside a mobile app APK can be reverse engineered with static binary analysis or with a MitM attack at runtime, and to solve this we will now see how we can remove the NASA API Key from being shipped inside the APK of the mobile app by delegating all the NASA API calls to an API reverse proxy. Now, you need to edit the API Key and API URL on the file to look like this: src/client/android/local.properties api.key= api.url=https://astropiks.demo.approov.io/v1/api.nasa.gov # The API key will no longer be compiled to the release binary (APK) Next, rebuild, install, and run the modified AstroPiks mobile app on the Android emulator or device as before. You should see the same result as before, but now the photos are being served through the API reverse proxy. You should see the photo requests being sent to the API reverse proxy on the Android Studio logs, you just need to look for entries tagged with ASTROPIKS_APP. If you do not see photos, double check the in the file, the network connectivity, and try to copy/paste the URL from the Android Studio logs to a browser and check if it works. api.url local.properties If you have been paying attention, you noticed that the API reverse proxy is indeed open to the public, because no API Key is being used, remember you left it blank in the file. To fix this you can add an API Key for the API reverse proxy calls, but then the attacker can also extract it and continue to use the Nasa API through your API reverse proxy. Although, this time you have an advantage, you can rate-limit the API requests to the API reverse proxy and temporarily block the offender IP address, but an attacker can learn via trial and error how to stay under the rate-limit, thus effectively bypassing your counter-measures to keep him at bay. local.properties To effectively defend your API reverse proxy you need to have the ability to distinguish with a very high degree of confidence that is doing the API request is indeed your original and unmodified mobile app and not an attacker, bots, or just someone curious poking around with your API via Postman or cURL requests, and in the next section you will learn how to do it. what SECURING THE API REVERSE PROXY WITH A MOBILE APP ATTESTATION TOKEN There is no longer any secret on the AstroPiks mobile app, but you have an API reverse proxy which can be used by anyone. You need a way to ensure that only trusted mobile apps can access your API reverse proxy server without requiring any new secrets on that mobile app. One way to do that is to use a dynamic Mobile App Attestation service to authenticate the mobile app as trustworthy to establish trust between the mobile app and the API reverse proxy server. We will now show how to modify the AstroPiks mobile app to work without static secrets while giving it the ability to prove to the API reverse proxy that it is the genuine and unmodified version that was uploaded to the official App store. You will be modifying the AstroPiks mobile app by changing just a few lines of code to integrate a third-party service SDK that will provide all the Mobile App Attestation service, and yes, the third-party service is us, Approov. You will integrate the Approov Mobile App Attestation service by integrating the Approov SDK in the mobile app. Once the Approov SDK is running in the AstroPiks mobile app (next section), the SDK will attest it using the Approov cloud service. WIth each Mobile App Attestation, a short-lived is returned representing the result of the Approov Mobile App Attestation by being signed with a shared secret for valid attestations and with an unknown secret for invalid attestations. The shared secret is only known by the Approov cloud service and by the API reverse proxy server, therefore it is never exposed to the mobile app. So, the JWT token needs to be added to the headers of each API request to be then validated by the API reverse proxy for a valid signature and expiration time. If valid, the API request can be fulfilled; otherwise a 400 response is returned. JSON Web token (JWT) AstroPiks Setup The API reverse proxy endpoint for the the Approov Mobile App Attestation example will be , therefore you need to open again your file and update it to look like this: v2 local.properties api.url=https://astropiks.demo.approov.io/v2/api.nasa.gov Now, if you launch the mobile app you will see that it fails to get the NASA pictures of the day, and this is because the API reverse proxy is not able to find the Approov token in the headers for the API request. We will fix it in the next section. Adding the Approov Mobile App Attestation Service If you don’t have an Approov account, then you should in order to be able to continue with the hands-on exercise. Follow the instructions in the onboarding email to get you ready to use the Approov Service. start a trial (no credit card) Next, you will add the missing Approov Mobile App Attestation functionality into your mobile app by following the for OkHttp. Approov Quickstart First, you need to add the Approov service dependency to the AstroPiks mobile app. Open the file and uncomment the line to enable jitpack in order to require the dependency from the Github repository: src/client/android/build.gradle Next, open the file and uncomment the last line to require the Approov service implementation: src/client/android/app/build.gradle Now, copy/paste from your onboarding email the Approov config string, or alternatively use the Approov CLI to get it: approov sdk -getConfigString Then, open the file and add to it the Approov config string (Note that it is not a secret): src/client/android/local.properties approov.config=#theapproovconfigstring= Even though the Approov config string is not a secret, just an identifier, you shouldn’t commit it into your source code. That is why we are adding it here. Now, go back to the file and uncomment the line that loads it into the default config as a resource value: src/client/android/app/build.gradle Next, synchronize Gradle, and if there are no errors you are ready to start using the Approov service in the AstroPiks mobile app. To use Approov, open the class and uncomment just three lines of code to import and enable the Approov service, but don’t uncomment the line for the Approov runtime secrets. You also need to comment out the native OkHttpClient so that the one wrapped by Approov is used. That will handle the instantiation and use of the Approov SDK for you. src/client/android/app/src/main/java/com/criticalblue/android/astropiks/App.java When finished your App application class should look like this: The changes you made introduce the Approov service which under the hood uses the Approov SDK to create an Approov Mobile App Attestation object. This object will periodically ask the Approov Mobile App Attestation cloud service to verify its authenticity, and it will cache the resulting short-lived validation token. For API calls to the mobile app backend, an interceptor object is also added which will intercept all API requests and add the most recent Approov token to the request headers. Testing the AstroPiks Integration with the Approov Mobile App Attestation Service As you already learned the Approov service locks down your mobile app to your API server, therefore you should let the Approov Mobile App Attestation service know which API will the mobile app be making requests to: approov api -add astropiks .demo .approov .io This means that from now on you can only test that the Approov integration works as expected in your mobile app by using a real mobile device, and the mobile app needs to be making the API request to an online server for the API domain you added. During the development phase of your mobile app you can continue to use localhost API servers and emulators by configuring the Approov Mobile App Attestation service to always issue valid Approov tokens for a specific device. Learn more at . Managing Devices Rebuild and run the AstroPiks mobile app . Sadly, the mobile app is still not showing photos! If it shows for you, then you forgot to update the in the file to use the API endpoint. in a real device api.url local.properties v2 If you have done everything correctly, the Approov service is now attesting the mobile app, but it is still returning a failed validation token. Until you register the mobile app with the Approov Mobile App Attestation service, the attestor has no idea how to validate your mobile app. This screen will also show if you run the mobile app in an emulator, because . Approov rejects emulators by default If you look into the Android Studio logs you will see several entries with a 401 response code: Let’s register the mobile app APK with the Approov Mobile App Attestation service so that the attestor can attest the mobile app. From the root of this repo execute: approov registration -add src /client/ android /app/ build /intermediates/ apk /debug/ app-debug.apk Before you restart the mobile app on your real device for the registration to propagate through the Approov cloud service infrastructure. you need to wait around 30 seconds Now, restart your mobile app , and If after restarting it you still don’t see the NASA pictures of the day and the logs still show 400 response codes, then it’s possible your Android Studio may be saving the APK in another location, therefore try registering with this command: on a real device approov registration -add src /client/ android /app/ build /outputs/ apk /debug/ app-debug.apk Now, you should be able to restart the mobile app and then see the pictures of the day: on your real device If you don’t see the pictures yet then you need to ensure you followed all the steps. Start by checking if the api.url and approov.config keys are correctly set in the file. local.properties NO FAKE MOBILE APPS The secret is no longer in the mobile app. The API reverse proxy server holds the NASA API key. The Approov Mobile App Attestation cloud service and the API reverse proxy server share a secret to establish trust between the mobile app and the API reverse proxy server. Is it possible to build a fake app without the API key? In Android Studio, try building a fake app by simply cleaning and rebuilding the existing app. Reinstall and run the freshly built app. Does it run successfully? Even though it has exactly the same functionality, this is not the same APK build so the attestation fails. If you want to use this new app, you must separately register this new version. During your mobile app development workflow this may slow you down, thus we advise you to configure Approov to always issue a valid token for a specific device. Learn more about this in the Approov docs at . Managing Devices HOW IS THIS BETTER THAN RUNTIME SECRETS PROTECTION? The AstroPiks mobile app is also used in the article to show how to remove static secrets from the mobile app without the need for an API Reverse Proxy. Therefore you may ask yourself which approach you should use for your own mobile app. Runtime Secrets Protection The Runtime Secrets Protection makes it very easy to start removing static secrets from your mobile app without the need for any backend implementation at all. You just add the Approov SDK to secure your mobile app, allowing it to fetch the just-in-time secret to make the API request. The secret is only delivered to genuine and unmodified versions of your mobile app, that are not under attack, by using Mobile App Attestation to secure the just-in-time runtime secret delivery. If you already have an API backend for your mobile app then we recommend that you use it to delegate the requests for any 3rd party API you need to use from your mobile app. In other words, use the Runtime Secrets Protection when you don’t have control of the API backend your mobile app is talking with, for example a 3rd party API or an API provided by another part of your organization. Integrating Approov on your backend will allow for a tight security between your mobile app and the API backends it needs to communicate with, because now the backend has a very high degree of confidence that the API request is indeed from it expects, a genuine and unmodified version of your mobile app, as uploaded to the app store. Any API request without a valid and not expired Approov token will be blocked, because it doesn’t come from your genuine mobile app - it may come from an ongoing MitM attack, a cloned or fake app, a bot, an attacker manually poking around with your API with cURL requests or with a tool like Postman, etc. what CONCLUSION When secrets were held inside the mobile apps, replacing a compromised one required an update to the existing installed mobile apps on users’ devices. Now, since the API keys are no longer on the mobile app binary, they can be easily changed in the API reverse proxy server without requiring any change to your installed base of mobile apps. Despite the extra hop, API reverse proxy servers offer enhanced security, scalability, and recovery benefits. Going Forward Thanks for reading! I’d really appreciate it if you recommend this tutorial (by clicking the ❤ button) so other people can find it. To learn more about API security and related topics, visit or follow @critblue on twitter. approov.io