Decompiling and extracting the bundle

The first step in auditing any React Native application is static bundle analysis. Because React Native packages all application logic into a single file, finding security omissions is significantly faster than in native code. For Android, we extract the bundle from the compiled APK:

# Unzip the APK to extract the assets folder
unzip app-release.apk -d extracted_apk
cd extracted_apk/assets/
# View the plain text JavaScript bundle
cat index.android.bundle | head -n 50

If the application utilizes the Hermes bytecode engine, the bundle is compiled into bytecode. We bypass this obfuscation using hbctool or custom Hermes decompilers to reconstruct the abstract syntax tree (AST) and extract static strings: API endpoints, hardcoded credentials, and cryptographic parameters.

The JavaScript Bridge: Intercepting cross-talk

React Native communicates with native system components (like camera, biometrics, and file systems) via the JS bridge. This bridge passes asynchronous JSON serialized messages. An auditor monitors this channel to identify: message tampering, privilege escalation, and execution injection.

We hook the bridge communication using custom Frida scripts during dynamic analysis, allowing us to inspect the payloads in real-time as they cross the boundary:

if (ObjC.available) {
  // Hook iOS RCTBridge message dispatch
  const bridge = ObjC.classes.RCTBridge;
  Interceptor.attach(bridge["- enqueueJSCall:method:args:completion:"].implementation, {
    onEnter: function (args) {
      const module = ObjC.Object(args[2]).toString();
      const method = ObjC.Object(args[3]).toString();
      const payload = ObjC.Object(args[4]).toString();
      console.log("[Bridge] Call -> Module: " + module + " | Method: " + method + " | Args: " + payload);
    }
  });
}

Bypassing SSL pinning and root/jailbreak checks

Many React Native fintech apps implement jailbreak detection (like react-native-jail-monkey) and certificate pinning. These controls are designed to prevent proxy inspection. However, they only delay an attacker. During a penetration test, we bypass these client-side checks using Frida scripting to force the application to trust our proxy certificate:

// Frida script snippet to bypass common RN jailbreak check returns
const JailMonkey = Java.use("com.gantix.jalmonkey.JailMonkeyModule");
JailMonkey.isJailBroken.implementation = function() {
    console.log("[Audit] Bypassing JailMonkey root check detection.");
    return false;
};

Local storage and state auditing

A common finding in React Native audits is the insecure storage of credentials. Developers frequently use AsyncStorage, which stores data in unencrypted SQLite databases at `/data/data/your.package/databases/RKStorage`. We extract this database from rooted devices or emulator testing frames and inspect the schema directly:

# Connect via ADB and view AsyncStorage SQLite file
adb shell
su
sqlite3 /data/data/com.fintech.app/databases/RKStorage
SELECT * FROM catalystLocalStorage;

If we find access tokens, session keys, or identity details (BVN, NIN) stored here, the finding is classified as High/Critical. Secure implementations must use `react-native-keychain` to bind cryptographic secrets to the device hardware keystore.

Manual validation required

Automated tools miss the logic

Automated tools scan React Native repositories for insecure packages but cannot verify if your custom bridge modules correctly validate input parameters, or if your local encryption uses hardware-backed security. Our manual mobile penetration testing process audits the active runtime of the app to confirm real protection.

Building a fintech app with React Native? Audit your code before shipping.

Book a React Native Pentest

Frequently asked questions

How does a penetration tester analyze a React Native app?

We perform a combination of static analysis (extracting and decompiling the javascript bundle or Hermes bytecode) and dynamic analysis (intercepting API traffic, inspecting local sqlite databases, and hooking native methods using Frida).

Can attackers bypass SSL pinning in React Native?

Yes. Even if you use libraries like react-native-ssl-pinning or native bridges, we can bypass certificate pinning in a dynamic review using Frida scripts that hook the underlying trust managers in OkHttpClient or TrustKit.

What is the security difference between React Native and native Android/iOS?

React Native introduces an additional attack surface: the JavaScript Bridge. Security controls must be implemented on both the native layer (Keystore/Keychain) and the JS layer, with strict validation on messages passing between them.

Related reading

Blog: React Native security pitfalls · Flutter security checklist · Reverse engineering Android apps

Services: Mobile penetration testing · Secure architecture review