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.
Related
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.
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.
I'm currently using Spotify in my Android app, but I am required to use a Secret in order to refresh tokens and such. I would like to transmit the secret from my Backend to the app, so the secret does not reside in the APK and cannot be found when decompiling. I've read a lot only about securing secrets in your app, via various ways like proxies, just using your own backend, putting the code into native C++ code (NDK) in the app or using the Hash of the app to determine whether the app is calling the backend, and not some guy behind his computer trying to steal the secrets.
Found options:
Proxy: It means routing it through my own server, don't want that
Own backend: Same as proxy, don't want all request to got trough my own service
Native code: Using this seems to slow down decompilers, but doesn't stop them
Hash: From what I could find, this post suggests some things that I consider weird. It is retrieving the SHA-1 and passing it into the network header to verify that the app is calling. The weird part about this is, that when you just unzip the APK file, running a printcert (keytool -printcert -file CERT.RSA) command will display all SHA and MD5 hashes of the APK. From what I can tell, this is not foolproof as someone can just get the hashes of the APK file and submit that to the server.
Is there any other way I can solve this issue?
YOUR PROBLEM
I'm currently using Spotify in my Android app, but I am required to use a Secret in order to refresh tokens and such. I would like to transmit the secret from my Backend to the app, so the secret does not reside in the APK and cannot be found when decompiling. I've read a lot only about securing secrets in your app, via various ways like proxies, just using your own backend, putting the code into native C++ code (NDK) in the app or using the Hash of the app to determine whether the app is calling the backend, and not some guy behind his computer trying to steal the secrets.
Congratulations in your efforts to understand the problem, it seems that you went to a great extent to understand that secrets in a mobile app can always be extracted by static binary analysis, but I don't see any mention to instrumentation frameworks 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.
or
xPosed
Xposed is a framework for modules that can change the behavior of the system and apps without touching any APKs. That's great because it means that modules can work for different versions and even ROMs without any changes (as long as the original code was not changed too much). It's also easy to undo.
but many others more exist, and all of them will hook into your code at runtime and extract any secret you store in your mobile app, no matter how securely you store it, even if you use hardware backed keystores, that run in a trusted execution environment:
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.
At some point the secret retrieved from this keystore will need to be used to make the request to your third party service, and at this point all an attacker needs to do is to hook on the call to that function and extract the secret when passed to it.
So no matter what you do in the end a secret in a mobile app can always be extracted, it just depends on the skill set of the attacker and the time and effort he is willing to put in.
This being said, it leads me to the point I am always advising developers to not do, that is calling Third Party services from within their mobile app.
THIRD PARTY SERVICES ACCESS FROM A MOBILE APP
Found options:
Proxy: It means routing it through my own server, don't want that
Own backend: Same as proxy, don't want all request to got trough my own service
Yes I read you don't want to use a proxy or your backend, but that is the best chance you have to secure the access to your third party service, in this case Shopify.
I wrote this article that explains why you should not do it from your mobile app, from where I quote:
Generally, all Third Party APIs require a secret in the form of an API key, Access Token or some other mechanism for a remote client to identify itself to the backend server with which it wishes to communicate. Herein lies the crux of the problem of accessing it from within your mobile app, because you will need to ship the required secret(s) within the code (the coloured keys in the above graphic).
Now you may say that you have obfuscated the secret within your code, hidden it in the native C code, assembled it dynamically at runtime, or even encrypted it. However, in the end all an attacker needs to do in order to extract this secret is to reverse engineer the binary with static binary analysis, or hook an instrumentation framework like Frida into the function at runtime which will return the secret. Alternatively an attacker can inspect the traffic between the mobile app and the Third Party API it is connecting to by executing a MitM (man-in-the-middle).
With the secret in their possession, the attacker can cause a lot of damage to an organization. The damage can be monetary, reputational and/or regulatory. Financially, the attacker can use the extracted secret to access your cloud provider and your pay-per-call Third Party APIs in your name, thus causing you additional costs. Further, you may be financially hurt by the exfiltration of data which may be sold to your competitors or used to commit fraud. Reputationally you can be impacted when the attacker uses the extracted secret to post on your behalf on social networks, creating a public relations nightmare. Another reputational damage can occur when an attacker uses the Third Party API and violates its terms & conditions (for example where frequent usage of the API triggers rate limits) such that you get blocked from using the service, creating pain for your end users. Last but not least are regulatory troubles caused when the extracted secret is the only mechanism of protecting access to confidential information from your Third Party API. If the attacker can retrieve confidential information such as Personal Identifiable Information (PII), regulatory fines connected to violations of GDPR in Europe, or the new CCPA Data Privacy Law in the California, may be enforced against your business.
So the take home message is that any secret you ship in your code must be considered public from the moment you release your app or push the code to a public repository. By now it should be clear that the best approach is to completely avoid accessing Third Party APIs from within a mobile app; instead you should always delegate this access to a backend you can trust and control, such as a Reverse Proxy.
You now may say that the problem have just shifted from the mobile app into the reverse proxy or backend server, and that's a positive thing, because the backend or reverse proxy is under your control, but a mobile app is out of your control, because it's in the client side, therefore the attacker can do whatever he wants with it.
In the backend or reverse proxy you are not exposing the secrets to access the third party services to the public, and any abuse an attacker wants to do in your behalf against that third party service will need to pass through a place you control, therefore you can apply as many defense mechanisms as you can afford and is required by law for your use case.
SECURITY IN DEPTH
putting the code into native C++ code (NDK)
When hiding the secret in native C code it's not easy to find it with static binary analysis, at least for script kids and seasonal hackers, it needs a better skill set that the majority may not have, thus I really recommend you to use it as an extra layer of security, but to protect a secret to access your own services, not third party ones as I already mentioned before.
If you really decide to follow my advice and shift your efforts to defend the third party secret in place you have control off, like your own backend, then I recommend you to read my answer to the question How to secure an API REST for mobile app? for the sections on Securing the API Server and A Possible Better Solution.
If you read the above answer then you have realized that if you keep the access to third party services in your backend, you can lock down your API server to your mobile app with a very high degree of confidence by using the Mobile App Attestation concept.
DO YOU WANT TO GO THE EXTRA MILE?
I saw that you are well informed, thus you already know what I am about to share, but in any response I gave to a security question I always like to reference the excellent work from the OWASP foundation, thus If you allow I will do it here to :)
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.
Everything that was created by a human can be broken down by a human - there is no completely secure option.
There are few things you can try though.
Use end-to-end encryption to establish a secure connection with you server and then send your secret to your app from your backend. Store secret secured via KeyStore in SharedPrefs or file or database.
Also you can leverage one-time pad cipher based on Vernam algorithm. It has absolute cryptographic strength thus cannot be cracked. In conjunction with Diffie-Hellman it may give a nice security boost.
It can still be cracked though - via memory scan on rooted devices while the app is active and has secret decrypted, via man-in-the-middle attack etc. As I've said - everything can be broken(for now except of Vernam algorithm maybe).
Don't bother too much with it though - it will be hard for criminals to significantly misuse your secrets. Generally they even don't bother with such stuff that much.
Hope this answer will help you somehow.
I am developing an Android application that uses Certificate Pinning (in a similar fashion such this).
However, I've came across dynamic instrumentation libraries such as Frida, or worse yet, Objection, that can bypass this safeguard.
I understand that security must be implemented on server side, but, I'd like to keep prying eyes outside my API. Moreover I also understand that Java executables are easy to disassemble and analyze.
How can I make this process more difficult for an attacker, i.e. make basic commands such as objection's
android sslpinning disable
fail and harden my app? I've seen that depending on the namings of the assets this process also crashes.
Any ideas?
Several harding frameworks can make it more difficult for Frida and similar tools to attach and manipulate the app process. However with enough time, motivation and/or money you can even break those frameworks.
However usually it is not the question "using a hardening framework or not" but "how many money are you willing to pay to get this little extra protection?
From my knowledge there are no free or even cheap hardening frameworks (please correct me if I am wrong and provide links to those free/cheap solutions with good protection), therefore it is just a question how much protection you want and how much you are willing to pay.
Note: Proguard and R8 are not hardening frameworks! They only just obfuscate the code a bit, but especially when it comes to certificate pinning and disabling this via Frida they do not offer any protection!
Possible Solution
How can I make this process more difficult for an attacker
A possible solution for your problem is to use a Mobile App Attestation solution to guarantee at run-time that your mobile app is not being MitM attacked, is not tampered, is not running in a rooted device, is not attached to a debugger and no instrumentation frameworks is present. This is achieved by running a SDK in the background that will communicate with a service running in the cloud to attest the integrity of the mobile app and the device is running on. The SDK in the mobile app doesn't make any decisions about the integrity of the app or mobile device, that is done in the cloud service, based on measurements provided by the mobile app.
So on a successful attestation of the mobile app integrity, by the cloud service, a short time lived JWT token is issued and signed with a secret that only the API server and the Mobile App Attestation service in the cloud are aware. In the case of failure on the mobile app attestation the JWT token is signed with a secret that the API server does not know.
Now the App must sent with every API call the JWT token in the headers of the request. This will allow the API server to only serve requests when it can verify the signature and expiration time in the JWT token and refuse them when it fails the verification.
Once the secret used by the Mobile App Attestation service is not known by the mobile app, is not possible to reverse engineer it at run-time even when the App is tampered, running in a rooted device or communicating over a connection that is being the target of a Man in the Middle Attack.
So this solution works in a positive detection model without false positives, thus not blocking legit users while keeping the bad guys at bays.
Any ideas?
You can try to roll your own solution or you can look for an existing Mobile App Attestation SAAS solution, like Approov(I work here), that provides SDKs for several platforms, including iOS, Android, React Native and others. The integration will also need a small check in the API server code to verify the JWT token issued by the cloud service. This check is necessary for the API server to be able to decide what requests to serve and what ones to deny.
Summary
In the end, the solution to use in order to protect your API server and mobile app must be chosen in accordance with the value of what you are trying to protect and the legal requirements for that type of data, like the GDPR regulations in Europe.
Going the Extra Mile
You seem to be into mobile app security, does I would like to recommend you:
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.
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: /