what are the penetration testing techniques for android application? - android

I developed an android application. I want to know the penetration techniques available for testing to secure my application. Can someone unzip my apk and get into my java files. I tried using apktool on my apk, all the java files converted into SMALI format. Is there any tool to convert my dex files back into java files?
I have already set debuggable false, so I think my logs won't be visible when someone try to dig in.
And, I have used hardcoded string even, I read it somewhere to use hardcoded strings.
Sorry, I missed out Diva tool & Apk Inspector, an app for testing but I am not able to use it properly.
What are the possibility that one can penetrate through my application and does obfuscation really help in preventing?
Any specific obfuscation to achieve that?

There are 2 main site about checking Android Security:
Open Android Security Assessment Methodology
Android Testing Cheat Sheet
In the first, Open Android Security Assessment Methodology, has the following sections:
OASAM-INFO: Information Gathering: Information gathering and attack surface definition.
OASAM-CONF: Configuration and Deploy Management: Configuration and deploy assessment.
OASAM-AUTH: Authentication: Authentication assessment.
OASAM-CRYPT: Cryptography: Cryptography use assessment.
OASAM-LEAK: Information Leak: Confidential information leak assessment.
OASAM-DV: Data Validation:User entry management assessment.
OASAM-IS: Intent Spoofing: Intent reception management assessment.
OASAM-UIR: Unauthorized Intent Receipt:Intent resolution assessment.
9 OASAM-BL Business Logic: Application business logic assessment.
In the second, Android Testing Cheat Sheet, it provides a checklist of tasks to be performed to do a penetration test of an Android application. It follows the OWASP Mobile Top 10 Risks list.
Here the documentation for the website:
Testing Methodology
At the device level, there are 2 ways in which the application shall be tested.
With Android device running in a factory default or normal mode
With Android device running in a rooted mode
At the application level, there are 2 ways in which it shall be tested
Application running on the device (to take benefits of touch related features)
Application running on the emulator (to ease the task of testing using wider screen of desktop or laptop)
Application Mapping
Map the application for possible security vectors
What is the application genre ? (Game, business, productivity etc)
Does the application connect to backend web services?
Is the application purely native or incorporates readymade frameworks?
Does the application store data on the device?
What all features of the device are used by the application? (camera, gyroscope, contacts etc)
OWASP Step-by-step Approach
(For each of the standards below, there shall be multiple steps for the tester to follow])
M1 - Weaker Server side controls
M2 - Insecure Data storage
This Section should be ideally tested after using the application for some time. This way application has time to store some data on the disk.
Commonplaces to look at
/data/data/app_folder
/sdcard/
/sdcard1/
M3 - Insufficient Transport Layer
Multiple layer of checks to be performed here
On Server side
Identify all ssl endpoints.
Perform SSL Cipher Scan using (sslscan)[1] or similar software.
SSLv2, SSLv3 is disabled
TLS 1.2, 1.1 and 1.0 is supported (1.2 is essential to ensure highest possible secure connection)
RC4 and CBC Based Ciphers are disabled
DH Params are >2048 Bits
SSL Certificate is signed with atleast sha2 / sha256
ECDHE Ciphers / Ciphers supporting Perfect forward secrecy are preferred
SSL Certificate is from Trusted RootCA
SSL Certificate is not expired
On Device Side
Ensure application is working correctly by navigating around.
Put a proxy in between the application and remote server. If application fails to load. Application might be doing cert validation. Refer logcat if any message is printed.
Place Proxy RootCA in trusted root CA list in device. (Burp)[2] (OWASP-ZAP)[3]
Try using application again. If application still doesn't connect, application might be doing cert pinning.
Install (Xposed Framework)[4] and (Just Trust Me)[5], enable JustTrustMe and then reboot device.
Try again if everything works we have a application which employee's cert pinning.
M4 - Unintended Data Leakage
Similar to M2 this section requires application to be used however while the application is in use we need to monitor following places.
adb logcat output
cache and webcache folder locations
M5 - Poor Authorization and Authentication
One of the simplest check's to be performed after application is used for some time and it has time to put the data inside system.
enumerate all exported activities
start each activity and identify if the activity was suppose to be publicly accessible or not.
Any activity displaying confidential information should be behind authentication. (confidential information includes PII (Personally identifiable data), financial data etc)
M6 - Broken Cryptography
There are multiple things to look at
Usage of known weak crypto algo's like Rot13, MD4, MD5, RC2, RC4, SHA1
Do it Yourself / let me design my own algo for encryption
Secret key hard coded in the application code itself.
M7 - Client Side Injection
Android applications need to store data locally in sqlite files or XML structures and hence need to performs either SQL/XML Queries or file I/O.
This gives rise to 2 major issues.
SQL / XML injection, and if the reading intent is publicly exposed another application could read this.
Local file read which can allow other application to read files of the application in question and if they contain sensitive data then data leakage via this media.
If the application is a HTML5 hybrid application then Cross Site Scripting (XSS) should also be considered. XSS will expose the entire application to the attacker as HTML5 applications will have the ability to call native functionality and hence control over the entire application.
M8 - Security Decisions via untrusted inputs
M9 - Improper Session Handling
Improper Session Handling typically results in the same outcomes as poor authentication. Once you are authenticated and given a session, that session allows one access to the mobile application. There are multiple things to look at
Check and validate Sessions on the Backend
Check for session Timeout Protection
Check for improper Cookies configuration
Insecure Token Creation
M10 - Lack of Binary Protection
Android Binaries are basically dex classes, which if not protected can result in an easy decompilation of source code. This could lead to code / logic leakage.
Following controls need to be checked for and validated:
Jailbreak Detection Controls
Checksum Controls
Certificate Pinning Controls
Debugger Detection Controls

You can try online apk decompilers and check what datas are visible. Then you can try to restrict your proguard up to your requirements.

Related

How to restrict usage of an API key with Hash comparison

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.

Securely Saving API Keys In Android (flutter) Apps

I know that this question has been asked many times. I've read all of them. I've searched this in Google but I still have questions that I wasn't able to find answers for.
Currently I'm storing API Keys in my app. Which yes is a bad practice. Now to the best of my knowledge I can use ProGaurd or DexGaurd to obfuscate. I can also use Keystore to securely store my api keys. Now for this part here' my question:
- Obfuscation changes the name of variables and classes. My API Key will still be in that app when someone decompiles the apk file. Sure it might take more time, but how much more is it? For example 20 minutes? I feel like the bottom line is that they can use this key if they put some time and effort. Am I getting this wrong?
Now the other answer that I've seen on different websites was that I can store my keys on a server and then communicate that through my app.
How is that even possible? A server is going to send the api key to the app. If the hacker finds this url they can just open it and get the key. If I use a key to access the URL then i'm entering a never ending loop of keys. How would I do this?
Someone said that I can encrypt my keys and then decrypt them in the app once it's received. But can't people decompile my decryption function and figure out my key?
I was also told that Firebase Remote Config is going to be a safe method for storing my keys. But then there's another problem
How much safer is this method?
If I'm using a google services json file to identify my project, can't just people get my keys from the remove config part? Because I can't see any settings for remove config on my console in order to say who can access this and who can't. How can I securely store my api keys on Firebase?
And can't hackers just decompile the apk and just change the code and extract data from my firebase account? Because the google services json is there. If they print the data extracted can they access everything?
So what exactly should I do to safely use api keys for my third party applications? And some of these api keys are very valuable and some of them just get information from other servers. I just want to know the safest method to store these keys.
HOW HARD CAN IT BE TO EXTRACT AN API KEY?
My API Key will still be in that app when someone decompiles the apk file. Sure it might take more time, but how much more is it? For example 20 minutes? I feel like the bottom line is that they can use this key if they put some time and effort. Am I getting this wrong?
You say For example 20 minutes?... Well it depends if you already have the tools installed in your computer or not, but if you have at least Docker installed you can
leverage some amazing open source tools that will make it trivial for you to extract the API Key in much less then 20 minutes, maybe around 5 minutes, just keep reading to see how you may do it.
Extract the API Key with Static Binary Analysis
You can follow my article about How to Extract an API Key from a Mobile App with Static Binary Analysis where you will learn how you may be able to do it under five minutes, and this without any prior hacking knowledge, from where I quote:
I will now show you a quick demo on how you can reverse engineer an APK with MobSF in order to extract the API Key. We will use the MobSF docker image, but you are free to install it in your computer if you wish, just follow their instructions to do it so.
To run the docker image just copy the docker command from the following gist:
#!/bin/bash
docker run -it --name mobsf -p 8000:8000 opensecurity/mobile-security-framework-mobsf
So after the docker container is up and running all you need to do is to visit http://localhost:8000 and upload your mobile app binary in the web interface, and wait until MobSF does all the heavy lifting for you.
Now if you have your API key hidden in native C/C++ code, then the above approach will not work, as I state in the same article:
By now the only API key we have not been able to find is the JNI_API_KEY from the C++ native code, and that is not so easy to do because the C++ code is compiled into a .so file that is in HEX format and doesn’t contain any reference to the JNI_API_KEY, thus making it hard to link the strings with what they belong to.
But don't worry that you can just use a Man in the Middle(MitM) Attack or an Instrumentation framework to extract the API key.
Extract the API Key with a MitM Attack
Just follow my article Steal that API Key with a Man in the Middle Attack to extract it in a device you can control:
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.
Oh but you may say that you use certificate pinning, therefore the MitM Attack will not work, and if so I invite you to read my article about Byapssing Certificate Pinning:
In a previous article we saw how to protect the https communication channel between a mobile app and an API server with certificate pinning, and as promised at the end of that article we will now see how to bypass certificate pinning.
To demonstrate how to bypass certificate pinning we will use the same Currency Converter Demo mobile app that was used in the previous article.
In this article you will learn how to repackage a mobile app in order to make it trust custom ssl certificates. This will allow us to bypass certificate pinning.
Extract with Instrumentation Framework
So if none of the above approaches works for you, then you can resort to use an instrumentation framework, like the very widely used 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.
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.
STORING API KEYS ENCRYPTED IN THE MOBILE APP?
Someone said that I can encrypt my keys and then decrypt them in the app once it's received.
So you can go with the 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 http request, and at this point all an attacker needs to do is to hook an instrumentation framework on the call to the function that returns the API key decrypted to extract it when is returned.
And to find the decrypt function all an attacker needs to do is to decompile your APK and find it as you already though off:
But can't people decompile my decryption function and figure out my key?
FIREBASE AND SAFETYNET FOR THE RESCUE?
I was also told that Firebase Remote Config is going to be a safe method for storing my keys.
Once more all the attacker needs to do is to use an instrumentation framework to extract all it needs from any function he identifies as using the Firebase config.
Oh but you may tell that Firebase and/or your mobile is protected with SafetyNET, then I need to alert you for the fact that SafetyNet checks the integrity of the device the mobile app is running on, not the integrity of the mobile app itself, as per Google own statement:
The goal of this API is to provide you with confidence about the integrity of a device running your app. You can then obtain additional signals using the standard Android APIs. You should use the SafetyNet Attestation API as an additional in-depth defense signal as part of an anti-abuse system, not as the sole anti-abuse signal for your app.
Also I recommend you to read this answer I gave to the question Android equivalent of ios devicecheck? in order to understand what a developer needs to be aware when implementing Safety Net in their mobile app.
So despite SafetyNet being a very good improvement for the Android security ecosystem it was not designed to be used as a stand-alone defence, neither to guarantee that a mobile app is not being tampered with, for that you want to use the Mobile App Attestation concept.
PROXY OR BACKEND SERVER
Now the other answer that I've seen on different websites was that I can store my keys on a server and then communicate that through my app.
How is that even possible? A server is going to send the api key to the app. If the hacker finds this url they can just open it and get the key. If I use a key to access the URL then i'm entering a never ending loop of keys. How would I do this?
While you may say this only shifts the problem from the mobile app to the proxy or backend server I have to say that at least the proxy or backend server is a thing under your control, while the mobile app isn't. Anyone who downlaods it can do whatever wants with it, and you can't have a direct control of, you can only add as many barriers you can afford into the APK to make it hard.
I recommend you to read my answer to the question How to restrict usage of an API key with Hash comparison? to better understand why you shouldn't try to secure your API keys in your mobile app, and instead move them to your backend or a proxy server.
POSSIBLE BETTER SOLUTION
So what exactly should I do to safely use api keys for my third party applications? And some of these api keys are very valuable and some of them just get information from other servers. I just want to know the safest method to store these keys.
The best advice I can give you here is to read my answer to the question How to secure an API REST for mobile app? to understand how you can indeed get ride of API keys in the mobile app and allow for your backend to have a high degree of confidence that the request is originated indeed from a genuine instance of your mobile app.
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 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.
If you think API Key should not be compromised then you should not put it inside the app. You can use the following possible solutions
You can keep your keys on a server and route all requests needing that key through your server. So as long as your server is secure then so is your key. Of course, there is a performance cost with this solution. You can use SSL pinning to authenticate the response. Check this
You can get the signature key of your app programmatically and send is to sever in every API call to verify the request. But a hacker can somehow find out the strategy.
Google does not recommend storing API keys in remote config but you can keep one token there and use it to verify the request and send the API key. Check this
In the case of the Android app, you can use SafetyNet API by Google to verify the authenticity of the app and the server can generate a token for the user after verification of the SafetyNet response. The token can be further used to verify the request. There is one plugin available for Flutter for SafetyNet API.
You can use a combination of the above approaches to ensure the security of the API key. To answer your questions, Firebase remote config uses SSL connection to transfer the data, it's very much secure but you should not rely on it completely for your data security. You also can't share API keys using the APIs which are publicly accessible. Moreover, storing both the encrypted key and the data inside the app won't make it secure.
You can use freeRASP for Android, iOS, and Flutter to mitigate the risk of Reverse Engineering.
The premium plans offer more protection such as App Integrity Cryptogram to protect APIs from app impersonation and Secure Storage SDK to protect assets at rest.

How to make my code secure and prevent from decompiling?

I created android app and it is working fine.
The issue is that when we decompile the app we can see all the code, so hacker can see our API URL and API Classes so they can clone the app.
So my question is that how can I secure my android app so I can protect it from hackers.
YOUR PROBLEM
I created android app and it is working fine. The issue is that when we decompile the app we can see all the code, so hacker can see our API URL and API Classes so they can clone the app.
Not matter what tool you use to obfuscate or even encrypt code, your API url will need to be in clear text at some point, aka when you do the API request, therefore it's up for grabs by an attacker. So if an attacker is not able to extract it with static binary analyses, it will extract at runtime with an instrumentation framework, 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.
So basically the attacker will need to find the place in the code where you do the API request, hook Frida on it, and extract the URL or any secret passed along with it to identify/authorize your mobile app in the API server.
Another approach the attacker can take is to perform a MitM attack in a mobile device he controls, and intercept the request being made to the API server:
Image sourced from article: Steal that API key with a Man in the Middle Attack
As you can see in the above example the intercepted API request, reveals the API server url and the API key being used.
POSSIBLE SOLUTIONS
So my question is that how can I secure my android app so I can protect it from hackers.
When adding security, no matter if for software or for a material thing, is always about layers, see the medieval castles for example, they don't have only one defense, they have several layers of it. So you should apply the same principle to your mobile app.
I will listed some of the minimal things you should do, but not an exhaustive list of them.
JNI/NDK
The JNI/NDK:
The Native Development Kit (NDK) is a set of tools that allows you to use C and C++ code with Android, and provides platform libraries you can use to manage native activities and access physical device components, such as sensors and touch input.
In this demo app I show how native C code is being used to hide the API key from being easily reverse engineered by static binary analyses, but as you already have seen you grab it with a MitM attack at runtime.
#include <jni.h>
#include <string>
#include "api_key.h"
extern "C" JNIEXPORT jstring JNICALL
Java_com_criticalblue_currencyconverterdemo_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
// To add the API_KEY to the mobile app when is compiled you need to:
// * copy `api_key.h.example` to `api_key.h`
// * edit the file and replace this text `place-the-api-key-here` with your desired API_KEY
std::string JNI_API_KEY = API_KEY_H;
return env->NewStringUTF(JNI_API_KEY.c_str());
}
Visit the Github repo if you want to see in detail how to implement it in your mobile app.
Obfuscation
You should always obfuscate your code. If you cannot afford a state of the art solution, then at least use the built in ProGuard solution. This increases the time and skills necessary to poke around your code.
Encryption
You can use encryption to hide sensitive code and data, and a quick Google search will yield a lot of resources and techniques.
For user data encryption you can start to understand more about it in the Android docs:
Encryption is the process of encoding all user data on an Android device using symmetric encryption keys. Once a device is encrypted, all user-created data is automatically encrypted before committing it to disk and all reads automatically decrypt data before returning it to the calling process. Encryption ensures that even if an unauthorized party tries to access the data, they won’t be able to read it.
And you can read in the Android docs some examples of doing it:
This document describes the proper way to use Android's cryptographic facilities and includes some examples of its use. If your app requires greater key security, use the Android Keystore system.
But remember, that using Frida will allow for an attacker to hook into the code that returns the data unencrypted, and extract it, but also requires more skill and time to achieve this.
Mobile App Attestation
This concept introduces a new way of dealing with securing your mobile app.
Traditional approaches focus to much on the client side, but in first place the data you want to protect is in the API server, and it's here that you want to have a mechanism that let's you know that what is making the request is really your genuine mobile app, the same you uploaded to the Google Play Store.
Before I dive into the role of the Mobile App Attestation, I would like to first clarify a misconception around what vs who is doing the API request, and I will quote this article I wrote:
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.
The Mobile App Attestation role is described in this section of another article I wrote, from where I quote the following text:
The role of a Mobile App Attestation service is to authenticate what is sending the requests, thus only responding to requests coming from genuine mobile app instances and rejecting all other requests from unauthorized sources.
In order to know what is sending the requests to the API server, a Mobile App Attestation service, at run-time, will identify with high confidence that your mobile app is present, has not been tampered/repackaged, is not running in a rooted device, has not been hooked into by an instrumentation framework (Frida, xPosed, Cydia, etc.) and is not the object of a Man in the Middle Attack (MitM). This is achieved by running an SDK in the background that will communicate with a service running in the cloud to attest the integrity of the mobile app and device it is running on.
On a successful attestation of the mobile app integrity, 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 know. In the case that attestation fails the JWT token is signed with an incorrect secret. Since the secret used by the Mobile App Attestation service is not known by the mobile app, it is not possible to reverse engineer it at run-time even when the app has been tampered with, is running in a rooted device or communicating over a connection that is the target of a MitM attack.
The mobile app must send the JWT token in the header of every API request. This allows the API server to only serve requests when it can verify that the JWT token was signed with the shared secret and that it has not expired. All other requests will be refused. In other words a valid JWT token tells the API server that what is making the request is the genuine mobile app uploaded to the Google or Apple store, while an invalid or missing JWT token means that what is making the request is not authorized to do so, because it may be a bot, a repackaged app or an attacker making a MitM attack.
So this approach will let your API server to trust with a very high degree of confidence that the request is coming indeed from the same exact mobile app you uploaded to the Google Play store, provided the JWT token has a valid signature and expire time, and discard all other requests as untrustworthy ones.
GOING THE EXTRA MILE
I cannot resist to recommend you the excellent work of the OWASP foundation, because no security solution for mobile is complete without going through The Mobile Security Testing Guide:
The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.
You can use DexGuard. Protecting Android applications and SDKs against reverse engineering and hacking.DexGuard offers extensive customization options to enable you to adapt the applied protection to your security and performance requirements.DexGuard prevents attackers from gaining insight into your source code and modify it or extract valuable information from it.
ProGuard is a generic optimizer for Java bytecode. DexGuard is a
specialized tool for the protection of Android applications.
Read Dexguard-vs-Proguard
you can use proguard which is by default provided by the Android studio while creating sign apk you can refer below document for that
Link: https://docs.google.com/document/d/1UgEZtKRoAIIXtPLKKHIds33txgU7hH33-3xsoBR4lWY/edit?usp=sharing
Apart from using code obfuscation there is not much you can do. I would recommend to use NDK layer for storing application secrets because C++ libraries can't be easily decompiled. You could use https://github.com/nomtek/android-client-secrets library for that purpose.
You can use ProGuard Tools to secure your code. It's renamed the remaining classes, fields, and methods using short meaningless names.
The API endpoints will always be open to end-users . But If you use the https and SSL in your api server the data will become encrypted like most of the apps. As for the API end-points, you can-not do anything
i found a website JavaDecompiler that will help you to decompile app. and the output of my research is there is no way to provide 100% code security. so what we can do for get accuracy is that put condition at frontend and backend both side.
and i had tried for dexguard but it was expensive for me and also proguard is not working well for me.

Make secure connection with a nodejs server providing API on Android

I have a website that store private information that can be accessed by request with a secret api key.
My Android application have to access that private information, and to do that it use a proxy server that store and use the secret api key to communicate with the website
The problem is that just using Wireshark, or finding the string in the app resources file, someone can see the proxy server url and use it to get the private data from the website
How can i make this system secure? how can i be sure that none else can use the proxy except the Android app?
Thank you!
I have a website that store private information that can be accessed by request with a secret api key.
From the moment you put a secret on the client is not anymore a secret, because now is public and anyone can see it by reverse engineer the app or by intercepting the traffic with a proxy or by just watching the traffic with the tool you mention, Wireshark.
My Android application have to access that private information, and to do that it use a proxy server that store and use the secret api key to communicate with the website
Using a proxy server doesn't solve the problem, because the proxy server doesn't know WHAT is calling it. As it stands the proxy server is open to the public that knows how to call it, as you already know and pointed out:
The problem is that just using Wireshark, or finding the string in the app resources file, someone can see the proxy server url and use it to get the private data from the website.
Another approach is to use a proxy tool like the MiTM Proxy that in my opinion will allow to extract more easily the API key, as you can see in the article Steal that API Key with a Man in the Middle Attack:
While we can use advanced techniques, like JNI/NDK, to hide the API key in the mobile app code, it will not impede someone from performing a MitM attack in order to steal the API key. In fact a MitM attack is easy to the point that it can even be achieved by non developers.
ADDRESSING YOUR QUESTIONS
How can i make this system secure? how can i be sure that none else can use the proxy except the Android app?
Well you bought yourself a very hard problem to solve, that a lot will say that is only possible to make it harder to be solved by the attacker, and this is true until some degree, because a lot of developers are not aware of the Mobile App Attestation concept, that allows a back-end server to only server requests comming from a original app.
Before I can explain you the concept I would like to clarify a common misconception among developers regarding the WHO vs WHAT is accessing your back-end server.
The Difference Between WHO and WHAT is Accessing the API Server
To better understand the differences between the WHO and the WHAT are accessing an API server, let’s use this picture:
The Intended Communication Channel represents the mobile app being used as you expected, by a legit user without any malicious intentions, using an untampered version of the mobile app, and communicating directly with the API server without being man in the middle attacked.
The actual channel may represent several different scenarios, like a legit user with malicious intentions that may be using a repackaged version of the mobile app, a hacker using the genuine version of the mobile app, while man in the middle attacking it, to understand how the communication between the mobile app and the API server is being done in order to be able to automate attacks against your API. Many other scenarios are possible, but we will not enumerate each one here.
I hope that by now you may already have a clue why the WHO and the WHAT are not the same, but if not it will become clear in a moment.
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.
OAUTH
Generally, OAuth provides to clients a "secure delegated access" to server resources on behalf of a resource owner. It specifies a process for resource owners to authorize third-party access to their server resources without sharing their credentials. Designed specifically to work with Hypertext Transfer Protocol (HTTP), OAuth essentially allows access tokens to be issued to third-party clients by an authorization server, with the approval of the resource owner. The third party then uses the access token to access the protected resources hosted by the resource server.
OpenID Connect
OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.
While user authentication may let the API server know WHO is using the API, it cannot guarantee that the requests have originated from WHAT you expect, the original version of the mobile app.
Now we need a way to identify WHAT is calling the API server, and here things become more tricky than most developers may think. The WHAT is the thing making the request to the API server. Is it really a genuine instance of the mobile app, or is a bot, an automated script or an attacker manually poking around with the API server, using a tool like Postman?
For your surprise you may end up discovering that It can be one of the legit users using a repackaged version of the mobile app or an automated script that is trying to gamify and take advantage of the service provided by the application.
Well, to identify the WHAT, developers tend to resort to an API key that usually they hard-code in the code of their mobile app. Some developers go the extra mile and compute the key at run-time in the mobile app, thus it becomes a runtime secret as opposed to the former approach when a static secret is embedded in the code.
The above write-up was extracted from an article I wrote, entitled WHY DOES YOUR MOBILE APP NEED AN API KEY?, and that you can read in full here, that is the first article in a series of articles about API keys.
First question
How can i make this system secure?
Depending on your budget and resources you may employ an array of different approaches and techniques to defend your API server, and I will start to enumerate some of the most usual ones, but before I do it so I would like to leave this note:
As a best practice a mobile app or a web app should only communicate with an API server that is under your control and any access to third party APIs services must be done by this same API server you control. This way you limit the attack surface to only one place, where you will employ as many layers of defense as what you are protecting is worth.
You can start with reCaptcha V3, followed by Web Application Firewall(WAF) and finally if you can afford it a User Behavior Analytics(UBA) solution.
Google 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.
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.
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.
All this solutions work based on a negative identification model, by other words they try their best to differentiate the bad from the good by identifying what is bad, not what is good, thus they are prone to false positives, despite of the advanced technology used by some of them, like machine learning and artificial intelligence.
So you may find yourself more often than not in having to relax how you block the access to the API server in order to not affect the good users. This also means that this solutions require constant monitoring to validate that the false positives are not blocking your legit users and that at same time they are properly keeping at bay the unauthorized ones.
Regarding APIs serving mobile apps a positive identification model can be used by using a Mobile App Attestation solution that guarantees to the API server that the requests can be trusted without the possibility of false positives, and I will explain it as a reply to your second question.
Second question
how can i be sure that none else can use the proxy except the Android app?
As I mentioned in the begin of my answer, the Mobile App Attestation concept may be your best option to tackle your problem.
The role of a Mobile App Attestation solution is to guarantee at run-time that your mobile app was not tampered with, is not running in a rooted device, not being instrumented by a framework like xPosed or Frida, not being MitM attacked, and this is achieved by running an SDK in the background. The service running in the cloud will challenge the app, and based on the responses it will attest the integrity of the mobile app and device is running on, thus the SDK will never be responsible for any decisions.
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.
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.
MiTM Proxy
An interactive TLS-capable intercepting HTTP proxy for penetration testers and software developers.
On successful attestation of the mobile app integrity 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.
The Mobile App Attestation service already exists as a SAAS solution at 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.
CONCLUSION
In the end, the solution to use in order to protect your API server 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.
DO YOU WANT TO GO THE EXTRA MILE?
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.

Avoid disabling certificate pinning Android

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.

Categories

Resources