How Secure is Your Mobile App? — Part 2 (Setup Android & iOS)

Muhammad Hanif
9 min readMar 11, 2021

--

cybernews.com

In part 1, I told about the definition of Penetration Testing, the report of Penetration Testing and the things we have to be concern about data security. How dangerous it is if we as Developer don’t secure our Mobile App. So, in part 2, I’m gonna share with you how to secure our Mobile App (Android & iOS).

We have to create a Mobile App project, whether it’s native (Java/Kotlin/Objective C/Swift) or hybrid (Ionic/React Native/Flutter). Let’s say we already have it.

Android

1. Code Obfuscation

To configure code obfuscation, I recommend to edit the code using Android Studio, not any code editor, because it won’t sync the whole project. Open Android Studio -> choose the project -> go to build.gradle (app module). Search for def enableProguardInReleaseBuildsand set to true.

Then, search for android.buildTypes.release. We have to enable code shrinking, obfuscation and optimization by adding minifyEnabled, also enable resource shrinking by adding shrinkResources. The boolean of its value must be set to true. Since we have made the enableProguardInReleaseBuilds variable with the true value, then we only need to use that variable.

After we set all configurations in build.gradle, we move to proguard-rules.pro file. This file is for configuring which code/class should be obfuscated and which code/class should not be obfuscated, there is some special case, if the class is obfuscated, it will get error. Wojtek Kaliciński already explained about how to use proguard-rules.pro and all of the basic formats about it, you can read it here. I usually find the rules by searching the project in Google, for example React Native project. It will show the default template of React Native proguard-rules.pro file, then copy-paste its code to ours.

Also, if we are using many libs, we can search its proguard-rules in Google, for example the SQLCipher lib. The result will be like this, copy-paste again to proguard-rules.pro file. And, here is the moment of truth, build and generate Android project. Open its APK file using APK Analyzer from Android Studio or JADX-GUI.

left: before implement code obfuscation, right: after implement code obfuscation

2. Root Detection

Root Detection is important for preventing the decompiling Android app, basically the attacker can access all the files inside app from rooting device. So, we need to handle it by detecting the rooted device. For React Native, we can use lib Jail-Monkey, just install it yarn add jail-monkey and see if it is working.

For Android Native, we can use lib Rootbeer. Add it in build.gradle (app module) -> dependencies. Then, implement its lib in MainActivity.java by defining RootBeer variable and add the condition if (rootBeer.isRooted()) .

root detection

3. SSL Pinning

SSL Pinning must be implemented when our app is communicating to API (Application Programming Interface), because client-server communication can be intercepted by attacker using tool, like Burpsuite. It can see all the GET/POST method, even it can see the parameters, headers and token, it is called Man in The Middle (MITM) attack. SSL Pinning can be achieved in 3 waysCertificate Pinning, Public Key Pinning & Hash Pinning. We will implement the Public Key Pinning.

First, we need sha256 key from certificate of our server. For example we want to hit https://medium.com. Run this syntax in terminal:

the output of running openssl syntax

In the end of output, there is sha256 key of its certificate, copy that key. Then, we need to create java class called SSLPinnerFactory.java, the code will be like this:

Then, call its class from MainApplication.java, put it on onCreate() method.

Then, we test it. There are 2 scenario tests:
1. hit https://medium.com with the right key
2. hit https://medium.com with the wrong key

In addition, we need to create the UI of its result, this is the example using React Native.

left: valid certificate, right: not valid certificate
left: log of valid certificate, right: log of not valid certificate

4. Background Screen Caching (Optional)

“Users information is leaked through Background Screen Caching”

It is something we don’t realize. In Apple documentation, they recommend to cover up sensitive information when the app is in the task switcher, because Apple always take snapshot of it. But, in Android, there is no background screen caching when the app is in task switcher. If we want to implement it, we just need 1 line of code in Main Application.java on onCreate() method.

left: window secure is not implemented, right: window secure is implemented

iOS

1. Jailbreak Detection

Jailbreak is the same as the root. We need to implement Jailbreak Detection in order to prevent the hooking by attacker. First of all, we have to know how to detect Jailbreak? There are many methods that attacker can hook, like using Cydia, RockApp, etc. Here is the explanation about it.

We will implement it in iOS native, because the Jail-Monkey lib can be bypassed using Liberty Lite (my issue in Jail-Monkey repository). Then, we need to use Xcode, the addition of header file and Objective C file cannot be detected using any code editor. So, open Xcode -> choose the project (.xcworkspace) -> create new file in project folder.

right click on project folder -> choose new file -> choose Objective-C File
name its file (JB) -> save it to default path (ios folder) -> click button create

Then, copy-paste this code to JB.m .

Next, we create the header file. It’s same like creating Objective-C file, but we choose header file and save it to default path (ios folder).

right click on project folder -> choose new file -> choose Header file -> name it (JB) -> save it default path (ios folder)

Then, copy-paste this code to JB.h.

Last, we need to call header file in Appdelegate.m. Put it on didFinishLaunchingWithOptions method, because it will detect Jailbreak device when the app is launching.

After that, we can build the whole project. If we find error like this:

isSecurityCheckPassed function is not detected in AppDelegate.m

we have to add manually file JB.m in Compile Sources section. Go to project folder -> choose Target SecureApp -> choose Build Phases -> open Compile Sources -> click “+” -> choose JB.m file -> click button Add. Then, build again, it will be success.

add JB.m file in Compile Sources section
jailbreak detection

2. SSL Pinning

SSL Pinning in iOS, we will use lib Trustkit. Add pod ‘Trustkit'first in podfile . Then, in terminal move to ios directory path, and run pod install .

After that, we need some configuration in AppDelegate.m file. Put it in didFinishLaunchingWithOptions method

left: valid certificate, right: not valid certificate
left: log of success SSL Pinning, right: log of error SSL Pinning

3. Background Screen Caching

Just like I explained before, Apple is taking snapshot for background screen, and using it as cache, that’s why the performance of Apple is really fast.

Remove sensitive information from views before moving to the background. When an application transitions to the background, the system takes a snapshot of the application’s main window, which it then presents briefly when transitioning your application back to the foreground. Before returning from your applicationDidEnterBackground: method, you should hide or obscure passwords and other sensitive personal information that might be captured as part of the snapshot.

On the other hand, there is sensitive data, probably like the financial app, banking app or app that shows sensitive information, it’s private and it must be protected to prevent the leaking.

To implement blur effect in task switcher, we need to configure it in AppDelegate.m

The task switcher is running when the app gets into the applicationWillResignActive method, then it will blur the screen by calling function nvs_blurPresentedView. After the user click the app again, it will come in the applicationDidBecomeActiveand un-blur the view.

left: the default app, right: blur in task switcher

4. NSAllowArbitaryLoads

NSAllowArbitaryLoads is a boolean value indicating whether App Transport Security (ATS) restrictions are disabled for all network connections. The default is true. It can produce the vulnerable application to Misconfigured ATS. An application may be misconfigured to allow loading of Arbitrary URLs in the application which may cause security concerns causing malicious behaviour in the application. So, we need to set it to false in info.plist.

set NSAllowArbitaryLoads to false

As conclusion, we already implemented:
1. Code obfuscation
2. Root/Jailbreak Detection
3. SSL Pinning
4. Background Screen Caching
5. NSAllowArbitaryLoads

The complete source code can be seen here:

All of this configurations can be said as the secure app, we don’t know the attackers out there can use any tools and various ways to break into the application (reverse-engineering), but it is out of our scopes, at least we tried to keep it safe and protect users data. It will be nice if there are any feedbacks about my article and always remember:

Data is the only thing that matters — Anonymous

--

--

Muhammad Hanif

Frontend Developer @Telkomsel. Part-time Runner @10.11Runners. Retail Investor @TLKM. Sport & Technology enthusiast.