How to tackle bots in REST APIs - android

I have a mobile application where users give advertise, other users view and accept it. Recently, I began to notice that bots started to give their own advertisements. I have moderators but there a so much advertisements that it is impossible to check everything (another challenge, is that bargain happens instantly, in realtime). It is classical REST API. I googled a lot and to my surprise can't find any open source solution that protects from illegal bot activities.
How do you tackle such cases?
Is it possible to eliminate it at all or I can only make their life more difficult taking some measures?

OPEN SOURCE BOT DETECTION
I googled a lot and to my surprise can't find any open source solution that protects from illegal bot activities.
If you search Github for bot detection you will land on this page https://github.com/topics/bot-detection?q=bot+detection&unscoped_q=bot+detection, that at this moment contains 7 results, that aren't very relevant, but if you remove the query string, and use https://github.com/topics/bot-detection you get 36 results, where some may be relevant depending on your backend language. You can also search using the terms browser detection, crawler detection, device detection, etc.
Some of this repos rely on the user-agent and/or in the IP address to detect the bot, and this approach is easily bypassed, because the user-agent header is easy to spoof and nowadays the attackers are using bot farms to rotate the ips, thus making it very hard to block them.
But should you use one of this repos? Why not, it's one more layer of defense, and at least you block the less sophisticated bots that don't run from a bot farm.
The Difference Between WHO and WHAT is Accessing the API Server
Recently, I began to notice that bots started to give their own advertisements.
Before we dive in how you can tackle the problem I want to first clear a misconception that is usual among developers of any seniority level, the difference between Who vs What is accessing the API server.
I recommend you to read the article Why Does Your Mobile App Need An Api Key? where I go in detail about the difference between Who and What is accessing your API server, but for your convenience 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.
So I want you to 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, that in your case are the bots.
THE API SERVER DEFENSES
How do you tackle such cases? Is it possible to eliminate it at all or I can only make their life more difficult taking some measures?
You can make the life of an attacker harder by applying defense in depth, by adding as many layers of defense as you can afford, and is required by law for your use case.
WAF - Web Application Firewall:
A web application firewall (or WAF) filters, monitors, and blocks HTTP traffic to and from a web application. A WAF is differentiated from a regular firewall in that a WAF is able to filter the content of specific web applications while regular firewalls serve as a safety gate between servers. By inspecting HTTP traffic, it can prevent attacks stemming from web application security flaws, such as SQL injection, cross-site scripting (XSS), file inclusion, and security misconfigurations.
The effectiveness, against APIs is weak, because it was designed more specifically for web apps that don't rely on API's, but still able to offer some degree of protection.
UBA - User Behavior Analytics:
User behavior analytics (UBA) as defined by Gartner is a cybersecurity process about detection of insider threats, targeted attacks, and financial fraud. UBA solutions look at patterns of human behavior, and then apply algorithms and statistical analysis to detect meaningful anomalies from those patterns—anomalies that indicate potential threats. Instead of tracking devices or security events, UBA tracks a system's users. Big data platforms like Apache Hadoop are increasing UBA functionality by allowing them to analyze petabytes worth of data to detect insider threats and advanced persistent threats.
A good example of a UBA solution is Recaptcha by Google, specially the reCAPTCHA V3:
reCAPTCHA is a free service that protects your website from spam and abuse. reCAPTCHA uses an advanced risk analysis engine and adaptive challenges to keep automated software from engaging in abusive activities on your site. It does this while letting your valid users pass through with ease.
...helps you detect abusive traffic on your website without any user friction. It returns a score based on the interactions with your website and provides you more flexibility to take appropriate actions.
When you use recaptcha V3 in a mobile app your API server can then verify the score for that request, but bear in mind that it only makes it more difficult to bypass, because if you search Google for bypass recaptcha V3 you will see a lot of solutions being offered as a service for attackers.
Lock the API server to the mobile app
It's possible for the API server to have a high degree of confidence that the request is indeed from your mobile app, and not from a bot by using the Mobile App Attestation concept, and I invite you to read my reply to the question How to secure an API REST for mobile app?, specifically the section 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 amazing work from the OWASP foundation.
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.
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.

Stopping bots is something we are already dealing with a lot. One of the common mechanisms is using captcha mechanisms (e.g. Googles recaptcha). Please google for it.

Related

How to use an API from my mobile app without someone stealing the token

I'm building an app that makes use of the OpenAI API
They provide me with an API token which I use to make the API calls from my android mobile app (react native)
I know it is a bad practice to store this API token on the mobile client because attackers might still it and use my quota and money.
What are my options? The trivial solution is to build a backend but I don't want to start implementing all the original API methods, I just prefer to use it directly from the client.
I've tried to store the token in a way that it cannot be found, but couldn't find a way.
Your Problem
They provide me with an API token which I use to make the API calls from my android mobile app (react native)
I know it is a bad practice to store this API token on the mobile client because attackers might still it and use my quota and money.
Yes, its indeed a very bad practice, but at least you are aware of the risks, while a lot use this approach without realising how easy its for an attacker to grab such secrets (Api tokens, API Keys, whatever you name them).
In a series of articles I wrote on Mobile API Security I show how easy it can be done with static analyses and with a MitM attack:
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.
Some attackers prefer to go straight to MitM attack, because they will learn how the App communicates with the API backend and will extract the secrets used, plus the blueprint they need to use for making the request and to parse the responses.
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.
Possible Solutions
Reverse Proxy
The trivial solution is to build a backend but I don't want to start implementing all the original API methods, I just prefer to use it directly from the client.
You don't need, you just need that your backend proxy the requests to the Third Party API you use on your mobile app, that in your case seems to be only for OpenAPI.
For example, when your mobile app needs to make a request to openapi.io/some/resource instead it makes it to your-reverse-proxy.com/some/resource that will then grab the /some/resource part and build the request to OpenAPI openapi.io/some/resource, adding the API token header to it, that now it's securely stored in your Reverse Proxy server.
Using a Reverse Proxy to Protect Third Party APIs
In this article you will start by learning what Third Party APIs are, and why you shouldn’t access them directly from within your mobile app. Next you will learn what a Reverse Proxy is, followed by when and why you should use it to protect the access to the Third Party APIs used in your mobile app.
A recurring theme in this article was the advice not to access Third Party APIs directly from a mobile app. As we have discussed, once your mobile app is released any secret in it becomes public, thus up for grabs by attackers to use on your behalf. If you are not careful you will be the one paying the bill or finding that your free tier resources have been exhausted by someone else.
The draw back of this approach is that you still have an API Key that you need to secure, the one to access the Reverse Proxy, but at least you are not exposing your OpenApi secret and you can use several mechanisms to throttle requests and to secure access to your Reverse Proxy to ensure that only answers to requests from genuine and unmodified instances of your mobile App.
Runtime Secrets Protection
You can devise or use an off the shelf mechanism to deliver the secrets to your mobile app just-in-time of them being required to be used on the API Request being made to OpenAPI, but you need to ensure that the secrets are only delivered to genuine and unmodified instances of your mobile app, that are not under a MitM attack, being tampered/instrumented at runtime with tools like Frida, otherwise your secret it will be easily extracted by hooking to the function that adds them to an header in the API request or by intercepting the request with MitM attack, even when the communication channel it's secured with certificate pinning, because it's not that hard to bypass in a device the attacker controls.
In my reply to the question Storing Api Keys Securely in Flutter or Sending Payment Details to my Server? I go in more detail on the Runtime Secret Protection approach.
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.

Android Frida script able to bypass root detection

I'm using flutter_jailbreak_detection to detect Roots in my flutter application. But attackers are able to bypass using the Frida script. So my question is how can we prevent it?
Thanks.
Frida Context
I'm using flutter_jailbreak_detection to detect Roots in my flutter application. But attackers are able to bypass using the Frida script.
The Frida framework is very powerful and not that hard to use to instrument code during runtime and when an attacker knows the public method name it needs to hook on at runtime it becomes even easier to bypass whatever he wants. For who doesn't know Frida and what is capable of just visit their website:
Inject your own scripts into black box processes. Hook any function, spy on crypto APIs or trace private application code, no source code needed. Edit, hit save, and instantly see the results. All without compilation steps or program restarts.
The attacker as his life facilitated due to the fact that your detection is done with a tool that exists on the public domain, therefore the attacker can learn how the tool detects a jailbroken device and hook on the method to make it always return False.
If you are not aware of how an attacker does it then I invite you to read an article I wrote about bypassing pinning with Frida. While the article doesn't show how to bypass the flutter_jailbreak_detection package, the principle of doing it its the same. Learn how to use a Frida script on a bypass attack by reading 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.
Now, that we are more aware and knowledgeable about Frida, how it works and its potential, we are in better position to understand that defending against its use it isn't an easy task, and we are also in better position to search and choose a solution(s) to defend against it.
Possible Solutions
So my question is how can we prevent it?
The best defence its the defence in depth where you employ as many solutions as you can and afford to mitigate the risks and effectively defend against attacks, and this isn't anything new, it's a principle with centuries of use in medieval castles and prisons.
Roll your own
You can try to roll you own detection or modify an open source one to use unknown method names, with code obfuscation, thus rendering the current approach of the attacker useless, but this will not take you too far, because the attacker will decompile your app to understand how you are doing it now, and depending on its skills set it will take him minutes, hours or days to bypass it again, even when code obfuscation is being used.
RASP - Runtime application self-protection
You can try to use RASP solutions for hardening your runtime, but once they work on the mobile app themselves, they may be bypassed at some point without your API backend beware of it in realtime in order to not fulfil the requests coming from the Mobile App that is being attacked.
RASP:
Runtime application self-protection (RASP) is a security technology that uses runtime instrumentation to detect and block computer attacks by taking advantage of information from inside the running software.
RASP technology is said to improve the security of software by monitoring its inputs, and blocking those that could allow attacks, while protecting the runtime environment from unwanted changes and tampering.
So, I am not saying you shouldn't use one, just be aware of it's limitations, like for the fact that it makes the decisions on the client side, thus outside your control, but when under attack it's making decisions in a device controlled by the attacker, therefore you may only realise that its being attacked when damage was already done, for example when your API was breached due to stolen credentials from your mobile app.
Mobile App Attestation
Alternatively you can use a Mobile App Attestation service, like Google Play Integrity:
The Play Integrity API helps protect your apps and games from potentially risky and fraudulent interactions, allowing you to respond with appropriate actions to reduce attacks and abuse such as fraud, cheating, and unauthorized access.
The Google Play Integrity service is a good starting point, but you cannot use it on every API call, because you will hit throttling from Google when you go above quotas, and throttling starts by delaying the time they take to respond to each attestation and ends-up with not being able to attest any-more for a period of time or until the mobile app its restarted.
Your last resort its to look for a Mobile App Attestation solution that doesn't throttle how many times your mobile app can attest, and I can point you at one (I work there), but I think I will do a better service to you if I point you to an article written by me that shows how our Mobile App Attestation solution can be used to protect a mobile app from attacks in realtime:
How to Protect Against Certificate Pinning Bypassing
Below you will learn how to use a mobile app attestation service to protect your API server from accepting requests that come from a mobile app where certificate pinning has been bypassed. This means that even though the attacker has bypassed the certificate pinning, he will not be able to receive successful responses from the API server. Instead, the server will always return 401 responses, thus protecting your valuable data from getting into the wrong hands.
While the article doesn't use Frida to bypass pinning in the demo attack to the mobile app, you can use the same steps I highlighted in the article How to Bypass Certificate Pinning with Frida on an Android App to attack the mobile with Frida and see the mobile app not being able to attest successfully with the cloud service, because it will get invalid tokens, that the API backend will not be able to verify as correctly signed, therefore a signal it shouldn't trust on the request and issue an error response, that effectively prevents the mobile app from working properly, once it doesn't get the expected data to work with.
Evaluate all you options carefully and choose one or more that fits your needs, resources and budget.
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.

Restrict face recognition API call to Flutter app only

I have an use case where in my flutter app makes an API call to a backend API which in turn makes a call to a 3rd party service to verify whether both the images are similar. My concern is, any user can use the api access token to call the backend API directly with spoofed data to get a verified profile. How can i make sure that the image data is coming from the mobile camera itself ?
The Difference Between WHO and WHAT is Accessing the API Server
I have an use case where in my flutter app makes an API call to a backend API which in turn makes a call to a 3rd party service to verify whether both the images are similar. My concern is, any user can use the api access token to call the backend API directly with spoofed data to get a verified profile.
You need to empower your backend API with a mechanism to distinguish between who is in the request vs what is making the request. 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 this:
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.
So 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.
After you understand this idea and it's ingrained in your mindset, you will look into mobile API security with another perspective, and you will be able to see attack surfaces that you never though they could exist.
Possible Solution
How can i make sure that the image data is coming from the mobile camera itself ?
I will reply to this question more in the context of how you can be sure that the request sent to the backend with the image is originated from your genuine and unmodified mobile app, and not from a tampered one or from a bot or manual request.
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 to understand the several options you have to tackle your problem.
From the several solutions provided in the answer the best fit for your problem will be the Mobile App Attestation, that will allow your backend to have a very high degree of confidence that what is making the request is indeed your genuine and unmodified mobile app, therefore preventing attacker from getting a valid profile, as per your main concern:
My concern is, any user can use the api access token to call the backend API directly with spoofed data to get a verified profile.
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.

Client Service Authentication to Backend

I am developing an Android background service that will communicate with a backend API. Also, the app will be distributed through a mobile device management system and there is no client interaction, such as inputting user info. How can I securely authorize each instance of the background service so they may access the backend service? One idea I had was to distribute one-time invitation codes with the app that were preconfigured on the server so each instance of the app may register with the service by generating a username and password, and then it could use OAuth to retrieve access tokens.
I found a similar question, however, I do not want to allow any arbitrary instance of the service to have access to the API and it references a deprecated feature
Authorizing Client Acces to App Engine Backend
The Challenge
I am developing an Android background service that will communicate with a backend API. Also, the app will be distributed through a mobile device management system and there is no client interaction, such as inputting user info.
You have got yourself a huge challenge here :)
Locking down the API server to genuine and unmodified instances of a mobile app is already a very hard task when user authentication(who) is involved, but when this is missing then things become really difficult, but not impossible.
Before we continue further I would like to first clear a misconception that I usually 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.
So 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.
In your case you don't have a user, therefore you will need to put your efforts on creating a solution that allows for the API server to have a very high degree of confidence that it can be sure that the request is from what it expects, a genuine and unmodified version of the mobile app where your Android background service is running.
Your Solution to the Challenge
One idea I had was to distribute one-time invitation codes with the app that were preconfigured on the server so each instance of the app may register with the service by generating a username and password, and then it could use OAuth to retrieve access tokens.
As you may be aware by now your solution will only provide the who in the request, not what is doing the request. The what in the request is already referenced by you when you say I do not want to allow any arbitrary instance of the service to have access to the API. This can be mobile apps instrumented at runtime, repackaged mobile apps, cloned mobile apps, bots running automated scritps to make request like the real mobile app or even manually replayed requests by an attacker.
Also, the one-time invitation codes can be easily extracted from the APK binary with reverse engineer techniques, like I show in 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.
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.
A Possible Better Solution
How can I securely authorize each instance of the background service so they may access the backend service?
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 linked answer will allow you to understand the several options you may want to consider, and also highlight the Mobile App Attestation concept as the one that will allow the API server to have a very high degree of confidence to only accept requests from genuine and unmodified instances of the mobile app running the Android background service.
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.

Restrict API requests to only my own mobile app

Is there any way to restrict post requests to my REST API only to requests coming from my own mobile app binary? This app will be distributed on Google Play and the Apple App Store so it should be implied that someone will have access to its binary and try to reverse engineer it.
I was thinking something involving the app signatures, since every published app must be signed somehow, but I can't figure out how to do it in a secure way. Maybe a combination of getting the app signature, plus time-based hashes, plus app-generated key pairs and the good old security though obscurity?
I'm looking for something as fail proof as possible. The reason why is because I need to deliver data to the app based on data gathered by the phone sensors, and if people can pose as my own app and send data to my api that wasn't processed by my own algorithms, it defeats its purpose.
I'm open to any effective solution, no matter how complicated. Tin foil hat solutions are greatly appreciated.
Any credentials that are stored in the app can be exposed by the user. In the case of Android, they can completely decompile your app and easily retrieve them.
If the connection to the server does not utilize SSL, they can be easily sniffed off the network.
Seriously, anybody who wants the credentials will get them, so don't worry about concealing them. In essence, you have a public API.
There are some pitfalls and it takes extra time to manage a public API.
Many public APIs still track by IP address and implement tarpits to simply slow down requests from any IP address that seems to be abusing the system. This way, legitimate users from the same IP address can still carry on, albeit slower.
You have to be willing to shut off an IP address or IP address range despite the fact that you may be blocking innocent and upstanding users at the same time as the abusers. If your application is free, it may give you more freedom since there is no expected level of service and no contract, but you may want to guard yourself with a legal agreement.
In general, if your service is popular enough that someone wants to attack it, that's usually a good sign, so don't worry about it too much early on, but do stay ahead of it. You don't want the reason for your app's failure to be because users got tired of waiting on a slow server.
Your other option is to have the users register, so you can block by credentials rather than IP address when you spot abuse.
Yes, It's public
This app will be distributed on Google Play and the Apple App Store so it should be implied that someone will have access to its binary and try to reverse engineer it.
From the moment its on the stores it's public, therefore anything sensitive on the app binary must be considered as potentially compromised.
The Difference Between WHO and WHAT is Accessing the API Server
Before I dive into your problem I would like to first clear a misconception about who and what is accessing an 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.
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 if you are not using user authentication in the app, then you are left with trying to attest what is doing the request.
Mobile Apps should be as much dumb as possible
The reason why is because I need to deliver data to the app based on data gathered by the phone sensors, and if people can pose as my own app and send data to my api that wasn't processed by my own algorithms, it defeats its purpose.
It sounds to me that you are saying that you have algorithms running on the phone to process data from the device sensors and then send them to the API server. If so then you should reconsider this approach and instead just collect the sensor values and send them to the API server and have it running the algorithm.
As I said anything inside your app binary is public, because as yourself said, it can be reverse engineered:
should be implied that someone will have access to its binary and try to reverse engineer it.
Keeping the algorithms in the backend will allow you to not reveal your business logic, and at same time you may reject requests with sensor readings that do not make sense(if is possible to do). This also brings you the benefit of not having to release a new version of the app each time you tweak the algorithm or fix a bug in it.
Runtime attacks
I was thinking something involving the app signatures, since every published app must be signed somehow, but I can't figure out how to do it in a secure way.
Anything you do at runtime to protect the request you are about to send to your API can be reverse engineered with tools like Frida:
Inject your own scripts into black box processes. Hook any function, spy on crypto APIs or trace private application code, no source code needed. Edit, hit save, and instantly see the results. All without compilation steps or program restarts.
Your Suggested Solutions
Security is all about layers of defense, thus you should add as many as you can afford and required by law(e.g GDPR in Europe), therefore any of your purposed solutions are one more layer the attacker needs to bypass, and depending on is skill-set and time is willing to spent on your mobile app it may prevent them to go any further, but in the end all of them can be bypassed.
Maybe a combination of getting the app signature, plus time-based hashes, plus app-generated key pairs and the good old security though obscurity?
Even when you use key pairs stored in the hardware trusted execution environment, all an attacker needs to do is to use an instrumentation framework to hook in the function of your code that uses the keys in order to extract or manipulate the parameters and return values of the function.
Android Hardware-backed Keystore
The availability of a trusted execution environment in a system on a chip (SoC) offers an opportunity for Android devices to provide hardware-backed, strong security services to the Android OS, to platform services, and even to third-party apps.
While it can be defeated I still recommend you to use it, because not all hackers have the skill set or are willing to spend the time on it, and I would recommend you to read this series of articles about Mobile API Security Techniques to learn about some complementary/similar techniques to the ones you described. This articles will teach you how API Keys, User Access Tokens, HMAC and TLS Pinning can be used to protect the API and how they can be bypassed.
Possible Better Solutions
Nowadays I see developers using Android SafetyNet to attest what is doing the request to the API server, but they fail to understand it's not intended to attest that the mobile app is what is doing the request, instead it's intended to attest the integrity of the device, and I go in more detail on my answer to the question Android equivalent of ios devicecheck. So should I use it? Yes you should, because it is one more layer of defense, that in this case tells you that your mobile app is not installed in a rooted device, unless SafetyNet has been bypassed.
Is there any way to restrict post requests to my REST API only to requests coming from my own mobile app binary?
You can allow the API server to have an high degree of confidence that is indeed accepting requests only from your genuine app binary by implementing the Mobile App Attestation concept, and I describe it in more detail on this answer I gave to the question How to secure an API REST for mobile app?, specially the sections 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.
No. You're publishing a service with a public interface and your app will presumably only communicate via this REST API. Anything that your app can send, anyone else can send also. This means that the only way to secure access would be to authenticate in some way, i.e. keep a secret. However, you are also publishing your apps. This means that any secret in your app is essentially being given out also. You can't have it both ways; you can't expect to both give out your secret and keep it secret.
Though this is an old post, I thought I should share the updates from Google in this regard.
You can actually ensure that your Android application is calling the API using the SafetyNet mobile attestation APIs. This adds a little overhead on the network calls and prevents your application from running in a rooted device.
I found nothing similar like SafetyNet for iOS. Hence in my case, I checked the device configuration first in my login API and took different measures for Android and iOS. In case of iOS, I decided to keep a shared secret key between the server and the application. As the iOS applications are a little bit difficult to reversed engineered, I think this extra key checking adds some protection.
Of course, in both cases, you need to communicate over HTTPS.
As the other answers and comments imply, you cant truly restrict API access to only your app but you can take different measures to reduce the attempts. I believe the best solution is to make requests to your API (from native code of course) with a custom header like "App-Version-Key" (this key will be decided at compile time) and make your server check for this key to decide if it should accept or reject. Also when using this method you SHOULD use HTTPS/SSL as this will reduce the risk of people seeing your key by viewing the request on the network.
Regarding Cordova/Phonegap apps, I will be creating a plugin to do the above mentioned method. I will update this comment when its complete.
there is nothing much you can do. cause when you let some one in they can call your APIs. the most you can do is as below:
since you want only and only your application (with a specific package name and signature) calls your APIs, you can get the signature key of your apk pragmatically and send is to sever in every API call and if thats ok you response to the request. (or you can have a token API that your app calls it every beginning of the app and then use that token for other APIs - though token must be invalidated after some hours of not working with)
then you need to proguard your code so no one sees what you are sending and how you encrypt them. if you do a good encrypt decompiling will be so hard to do.
even signature of apk can be mocked in some hard ways but its the best you can do.
Someone have looked at Firebase App Check ?
https://firebase.google.com/docs/app-check
Is there any way to restrict post requests to my REST API only to requests coming from my own mobile app binary?
I'm not sure if there is an absolute solution.
But, you can reduce unwanted requests.
Use an App Check:
The "Firebase App Check" can be used cross-platform (https://firebase.google.com/docs/app-check) - credit to #Xande-Rasta-Moura
iOS: https://developer.apple.com/documentation/devicecheck
Android: https://android-developers.googleblog.com/2013/01/verifying-back-end-calls-from-android.html
Use BasicAuth (for API requests)
Allow a user-agent header for mobile devices only (for API requests)
Use a robots.txt file to reduce bots
User-agent: *
Disallow: /

Categories

Resources