There are so many articles about circumventing SSL Pinning in Android by using CertificatePinner class in OkHttp3.
https://medium.com/#hojat.sajadinia/bypass-okhttp-certificatepinner-on-android-9a45ad80a58b
https://blog.nviso.eu/2019/04/02/circumventing-ssl-pinning-in-obfuscated-apps-with-okhttp/?fbclid=IwAR3QRvecJl6rlmpN_fpbBGgY2Bvrax3eo-Y7qOf7StYW7_aGsuaIdrr_pQs
https://joncooperworks.medium.com/disabling-okhttps-ssl-pinning-on-android-bd116aa74e05
So my question is, what i should do in preventing bypass SSLPinning by using OkHttp.CertificatePinner ?
What i tried is to obfuscate OkHttp in my project. The OkHttp3 class not found when we reverse the APK file by using ApkTools, but when i use jadx to reverse the APK file, the OkHttp3 doesn't get obfuscated in dex file.
You can probably investigate device attestation to confirm the right app binary is running on a non rooted mobile. https://developer.android.com/training/safetynet/attestation
The SafetyNet Attestation API is an anti-abuse API that allows app developers to assess the Android device their app is running on. The API should be used as a part of your abuse detection system to help determine whether your servers are interacting with your genuine app running on a genuine Android device.
But I'm not qualified to provide expert advice on this topic.
Finally i had to override mapping.txt manually since proguard rules doesn't works on OkHttp3. Hopefully after i overrode the class name, method name and object name of OkHttp3 would able to prevent man-in-the-middle attackers to bypass certificate pinning by using Okhttp3.CertificatePinner.java
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.
We have a challenge that reverse engineer modding our App and change some behavior of it and repack it.
We added a App signature checking to code but the reverse engineer can found that part and disabled it.
the another challenge is the third-party API we use must done on client and we can't perform it on server.
Anyone have idea to increase security of App ?
I have 3 things in mind for security.
use proguard for code deobfuscation
write native code for your secured part. It can't be reverse engineered
or process your secured part in server side & use the result.
I will start with a very very short introduction on OS certificate pinning for Android. Starting with version 4.2 of Android system/OS level SSL/TLS certificate pinning was introduced (see also this URL for more info.). The list of pinned certificates using this mechanism is located at: "/data/misc/keychain/pins" and contains by default around 40 entries for Google services like mail.google.com, youtube.com, etc. I would very much like to have my own certificate pinned by having it added to this list. However, modifying this list requires an Android permission (android.permission.WRITE_SECURE_SETTINGS) that's only available to system apps.
Doe anyone know if there might by some kind procedure in place at Google to submit a request to be added to this list (i.e. /data/misc/keychain/pins)?
WebViews are tricky, not least because there is no perfect way to implement pinning in them except with Android N using Network Security Configuration.
The best you can do is override shouldInterceptRequest and implement the network calls yourself using one of the methods described in Android Security: SSL Pinning, however this only intercepts GET requests so if your WebViews use POST requests then you are out of luck. Android-SSL-Pinning-WebViews shows an example of doing this.
The challenge I have is to convert an android app that uses HTTP connection to HTTPS connection without rewriting the code?
What are the options available to achieve the above challenge on a device without a root access?
Any solution that relies on server-side redirections (from HTTP to HTTPS) will be vulnerable to MITM attacks (see this answer).
If the addresses in this app are configurable, just change them to use your HTTPS URLs.
Otherwise, you can of course use a server-side redirection to mitigate the risk slightly, but that won't prevent downgrade MITM attacks (which can happen, perhaps more so when using a mobile device).
If it's always connecting to a known endpoint that's under your control, you could implement something at the target server end of things to redirect, perhaps something like mod_rewrite if it's an Apache server.
There's no much to be rewritten. You basically change your http:// links to https:// and that's shall be it. Some problems may appear when endpoint's certificate is self signed or signed by some less popular CA, but you can easily replace your HttpClient with this one, add issuer's CA to your app and be done with one screen of code basically.
If app is not yours and you got no code, then you could try to tunnel it, by making it accessing the net via your access point which would transparently re-route the packets via ssh tunnel or VPN or whatever else.
If app is not yours but you can have code - that's IMHO best way to go.