Your Mobile App Problem
I have a mobile app and users cheat on my app too. In the application, I provide a link to the PHP code with AsyncTask and JSONObject. So far, so good.
A mobile app runs on the client device, therefore it's running in an untrusted environment. All its code must be considered public, including secrets and URLs to the API endpoints and knowing how to call and attack that API endpoints is not hard to learn.
Let's see why...
Why its public and untrusted?
Because open source tools exist to make it trivial to reverse engineer the app binary statically to be able to analyse the code and learn how it works, extract secrets, API URLs and even modify it's code to repackage the mobile app and install it again on the device.
For example, I wrote an article that shows how easy is too reverse engineer a mobile app binary, that goes by the title 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.
During this article we will use the Android Hide Secrets research repository that is a dummy mobile app with API keys hidden using several different techniques.
Learn how to call and attack the API endpoints
This one is not hard to achieve, because several open source tools can help us with the task of performing a Man in the Middle (MitM) attack, where we intercept all the communications between the mobile app and the API servers, even when HTTPs is used. This will allow us to inspect/modify the requests and responses at will and we can even replay requests from the MitM tool.
A common defense against MitM attacks is to implement certificate pinning in the mobile app, and you can see how its done in the article Securing HTTPS with Certificate Pinning:
In order to demonstrate how to use certificate pinning for protecting the https traffic between your mobile app and your API server, we will use the same Currency Converter Demo mobile app that I used in the previous article.
In this article we will learn what certificate pinning is, when to use it, how to implement it in an Android app, and how it can prevent a MitM attack.
Unfortunately, once the user/attacker is in control of his device he can use other open source tools to bypass certificate pinning and be able to perform the MitM attack, like I show in the article How to Bypass Certificate Pinning with Frida on an Android App to show you how to do it:
Today I will show how to use the Frida instrumentation framework to hook into the mobile app at runtime and instrument the code in order to perform a successful MitM attack even when the mobile app has implemented certificate pinning.
Bypassing certificate pinning is not too hard, just a little laborious, and allows an attacker to understand in detail how a mobile app communicates with its API, and then use that same knowledge to automate attacks or build other services around it.
With this methodology the user/attacker can easily modify the value of the reward at runtime with MitM tool or with a Frida script.
Firebase is not enough
And I created few secret keys with Firebase Firestore. And I defined these keys in my PHP code. I assigned secret keys from Firestore to a String. I don't know if there will be a problem.
With the use of Frida the attacker can hook at runtime into the mobile app and extract the secret that its returned from Firebase and then reuse it in a repackaged app, from a web app or even from a simple cURL request.
For example while this article shows an example of how to use Frida to hook at runtime in a function on iOS, the process for Android is equivalent:
Now we have enough information to get the data ourselves:
const firebase = require("firebase");
const util = require('util')
var firebaseConfig = {
apiKey: "<redacted>",
authDomain: "<redacted>",
databaseURL: "<redacted>",
projectId: "<redacted>",
storageBucket: "<redacted>",
messagingSenderId: "<redacted>",
appId: "<redacted>",
};
firebase.initializeApp(firebaseConfig);
var database = firebase.firestore();
["<redacted>", "<redacted>"].forEach(collection => {
database.collection(collection).get().then(function(querySnapshot) {
console.log(`Data for ${collection}:`);
querySnapshot.forEach((doc) => {
var data = doc.data();
console.log(util.inspect(data, false, null, true));
});
}).catch(function (error) {
console.log("Error getting document:", error);
});
});
Extracting the secret from Firebase is not that hard and once the attacker has it then he can reuse it from anywhere he wants, because the user agent protection in your code is trivial to bypass:
agent = $_SERVER['HTTP_USER_AGENT'];
All the attacker needs to do is to add the correct header to the API request.
Rewards Tampering
But the problem is, When they receive a reward in the app, the value of the reward is 5, while some users cheat by making it 5000.
If you have read all of the above you are now aware of several ways of tampering with your rewards scheme:
- Reverse engineer the mobile app binary, change code and repackage the mobile app.
- Perform a MitM attack to understand how the API works and then automate the requests outside the mobile app.
- Hook at runtime into the code a modify it to change the rewards amount or to extract the secret from Firebase in order to automate API requests outside the mobile app.
If I was the attacker I would use Frida to extract the secret from Firebase and then modify the mobile app code to remove the Firebase call and replace it with the harcoded secret. Afterwards I would repackage the mobile app and install it again.
Possible Solutions
But still, some users can cheat. How can I solve this, or preserve API links, or update the MySQL table more securely?
To ensure your users can not cheat on you you will need to employ as many defenses as you can. You will need to secure your API in such a way that its able to know that what is making the request it's indeed a genuine and unmodified version of your mobile app, not a cURL request, repackaged mobile app, MitM tool or any other unauthorized way. The mobile app itself will need to also use hardening and shieding protections.
To better understand how you can go about all this defenses 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.
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.