Securing Apps In React Native
Tags: reactnative, android, ios, security
Published: 2024-04-19 05:18:58

## **a) JailMonkey** ([Ref.](https://www.npmjs.com/package/jail-monkey))

JailMonkey is a React Native library designed to detect potential security threats on a user’s device. It includes several checks to determine if a device is jailbroken (iOS) or rooted (Android). Let’s delve into some key security checks provided by JailMonkey

Some apps need to protect themselves in order to protect data integrity. JailMonkey allows you to:

- Identify if a phone has been jail-broken or rooted for iOS/Android.
- Detect mocked locations for phones set in "developer mode".
- (ANDROID ONLY) Detect if the application is running on external storage such as an SD card.

## Installation:

```
yarn add jail-monkey
or
npm install jail-monkey
```

## Usage:
Then inside App.js add,

```
import JailMonkey from 'jail-monkey';
import RNExitApp from 'react-native-exit-app';

  const checkJailMonkey = useCallback(() => {
    const isJailBroken = JailMonkey.isOnExternalStorage() || JailMonkey.isJailBroken();
    if (isJailBroken && !__DEV__) {
      Alert.alert(
        textString.securityWarning,
        textString.jailBrokenWarning,
        [{ text: 'OK', onPress: () => RNExitApp.exitApp() }],
        { cancelable: false }
      );
    }
  }, []);

  useEffect(() => {
checkJailMonkey()
  }, []);
```

---
--------------------------------------------------------------
---

## **b) React Native Code Obfuscation**

### Introduction
Code obfuscation is a technique used to make code difficult to understand and analyze. In React Native, code obfuscation can be used to protect intellectual property, prevent reverse engineering, and improve the security of your application.

We will separately obfuscate javascript, native android and ios.

---

### 1. For React Native **Javascript** part: ([Ref.](https://medium.com/@aqeel_ahmad/code-obfuscation-in-react-native-a-comprehensive-guide-46a9f8bedd95))

**Obfuscate React Native Code using Metro Plugin**

a) Install:

```
npm i -D obfuscator-io-metro-plugin
or
yarn add -D obfuscator-io-metro-plugin
```

b) Once the plugin is installed, you will need to add it to your Metro configuration file. You can do this by adding the following code to your `metro.config.js` file:

```
const jsoMetroPlugin = require("obfuscator-io-metro-plugin")(
  {
    // for these option look javascript-obfuscator library options from  above url
    compact: false,
    sourceMap: false, // source Map generated after obfuscation is not useful right now so use default value i.e. false
    controlFlowFlattening: true,
    controlFlowFlatteningThreshold: 1,
    numbersToExpressions: true,
    simplify: true,
    stringArrayShuffle: true,
    splitStrings: true,
    stringArrayThreshold: 1,
  },
  {
    runInDev: false /* optional */,
    logObfuscatedFiles: true /* optional generated files will be located at ./.jso */,
  }
);

module.exports = {
  transformer: {
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: false,
      },
    }),
  },
  ...jsoMetroPlugin,   /*add this line in your previous module after defined above*/
};
```
_Note: add   `*.jso`   in .gitignore_

---
### 2. For React Native **Android** part: [Ref.](https://developer.android.com/build/shrink-code#enable)

Note: We are using R8 here for code obfuscation. 

In `android/app/build.gradle`, add:

```
def enableProguardInReleaseBuilds = true
.
.
.

    buildTypes {
        debug {        }
        release {
debuggable false // Disable debugging for release builds

shrinkResources enableProguardInReleaseBuilds // Enable resource shrinking in release builds if ProGuard is enabled

minifyEnabled enableProguardInReleaseBuilds // Enable code minification and obfuscation in release builds if ProGuard is enabled

proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" // Use default ProGuard optimization rules along with custom rules defined in "proguard-rules.pro"
```

Then in `android/app/proguard-rules.pro` at last add/keep as per your project requirement(Keeping all classes and members in):

```
-keep class io.invertase.firebase.** { *; }
-dontwarn io.invertase.firebase.**

-keep class com.awrostamani.BuildConfig { *; }
-keep class com.swmansion.reanimated.** { *; }
-keep class com.facebook.react.turbomodule.** { *; }
-keep public class com.horcrux.svg.** {*;}
```
_Note: If app still crashes after proguard enabling, then check app in release mode/crashlytics which library is doing so and add that also in `proguard-rules.pro`_


Make a release build and check using any online tool like [Link](http://www.javadecompilers.com/apk) to check if the actual code is hidden/converted to random strings.

---

### 3. For React Native **iOS** part: ([Ref.](https://stackoverflow.com/a/54282723/9377254))
There is no built-in library in the iOS project that will obfuscate your code, therefore an external package has to be used.

---

---

---

## **c) Using secure storage for sensitive data:**

React native mmkv/react native keychain can be used.
[Link MMKV](https://dev.to/ajmal_hasan/react-native-mmkv-5787)
[Link Keychain](https://dev.to/ajmal_hasan/biometric-authentication-with-react-native-keychain-5ac8)

---

_To be continued..._