React Native Application Analysis

Reading time: 10 minutes

tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

To confirm if the application was built on the React Native framework, follow these steps:

  1. Rename the APK file with a zip extension and extract it to a new folder using the command cp com.example.apk example-apk.zip and unzip -qq example-apk.zip -d ReactNative.

  2. Navigate to the newly created ReactNative folder and locate the assets folder. Inside this folder, you should find the file index.android.bundle, which contains the React JavaScript in a minified format.

  3. Use the command find . -print | grep -i ".bundle$" to search for the JavaScript file.

Note: If you are given an Android App Bundle (.aab) instead of an APK, generate a universal APK first and then extract the bundle:

bash
# Get bundletool.jar and generate a universal APK set
java -jar bundletool.jar build-apks \
  --bundle=app-release.aab \
  --output=app.apks \
  --mode=universal \
  --overwrite

# Extract the APK and then unzip it to find assets/index.android.bundle
unzip -p app.apks universal.apk > universal.apk
unzip -qq universal.apk -d ReactNative
ls ReactNative/assets/

Javascript Code

If checking the contents of the index.android.bundle you find the JavaScript code of the application (even if minified), you can analyze it to find sensitive information and vulnerabilities.

As the bundle contains actually all the JS code of the application it's possible to divide it in different files (potentially making easier its reverse engineering) using the tool react-native-decompiler.

Webpack

To further analyze the JavaScript code, you can upload the file to https://spaceraccoon.github.io/webpack-exploder/ or follow these steps:

  1. Create a file named index.html in the same directory with the following code:
html
<script src="./index.android.bundle"></script>
  1. Open the index.html file in Google Chrome.

  2. Open the Developer Toolbar by pressing Command+Option+J for OS X or Control+Shift+J for Windows.

  3. Click on "Sources" in the Developer Toolbar. You should see a JavaScript file that is split into folders and files, making up the main bundle.

If you find a file called index.android.bundle.map, you will be able to analyze the source code in an unminified format. Map files contain source mapping, which allows you to map minified identifiers.

To search for sensitive credentials and endpoints, follow these steps:

  1. Identify sensitive keywords to analyze the JavaScript code. React Native applications often use third-party services like Firebase, AWS S3 service endpoints, private keys, etc.

  2. In this specific case, the application was observed to be using the Dialogflow service. Search for a pattern related to its configuration.

  3. It was fortunate that sensitive hard-coded credentials were found in the JavaScript code during the recon process.

Quick secrets/endpoint hunting in bundles

These simple greps often surface interesting indicators even in minified JS:

bash
# Common backends and crash reporters
strings -n 6 index.android.bundle | grep -Ei "(api\.|graphql|/v1/|/v2/|socket|wss://|sentry\.io|bugsnag|appcenter|codepush|firebaseio\.com|amplify|aws)"

# Firebase / Google keys (heuristics)
strings -n 6 index.android.bundle | grep -Ei "(AIza[0-9A-Za-z_-]{35}|AIzaSy[0-9A-Za-z_-]{33})"

# AWS access key id heuristic
strings -n 6 index.android.bundle | grep -E "AKIA[0-9A-Z]{16}"

# Expo/CodePush deployment keys
strings -n 6 index.android.bundle | grep -Ei "(CodePush|codepush:\\/\\/|DeploymentKey)"

# Sentry DSN
strings -n 6 index.android.bundle | grep -Ei "(Sentry\.init|dsn\s*:)"

If you suspect Over-The-Air update frameworks, also hunt for:

  • Microsoft App Center / CodePush deployment keys
  • Expo EAS Updates configuration (expo-updates, expo\.io, signing certs)

Change JS code and rebuild

In this case changing the code is easy. You just need to rename the app to use the extension .zip and extract it. Then you can modify the JS code inside this bundle and rebuild the app. This should be enough to allow you to inject code in the app for testing purposes.

Hermes bytecode

If the bundle contains Hermes bytecode, you won't be able to access the Javascript code of the app (not even to the minified version).

You can check if the bundle contains Hermes bytecode by running the following command:

bash
file index.android.bundle
index.android.bundle: Hermes JavaScript bytecode, version 96

However, you can use the tools hbctool, updated forks of hbctool that support newer bytecode versions, hasmer, hermes_rs (Rust library/APIs), or hermes-dec to disassemble the bytecode and also to decompile it to some pseudo JS code. For example:

bash
# Disassemble and re-assemble with hbctool (works only for supported HBC versions)
hbctool disasm ./index.android.bundle ./hasm_out
# ...edit ./hasm_out/**/*.hasm (e.g., change comparisons, constants, feature flags)...
hbctool asm   ./hasm_out ./index.android.bundle

# Using hasmer (focus on disassembly; assembler/decompiler are WIP)
hasmer disasm ./index.android.bundle -o hasm_out

# Using hermes-dec to produce pseudo-JS
hbc-disassembler ./index.android.bundle /tmp/my_output_file.hasm
hbc-decompiler   ./index.android.bundle /tmp/my_output_file.js

Tip: The open-source Hermes project also ships developer tools such as hbcdump in specific Hermes releases. If you build the matching Hermes version used to produce the bundle, hbcdump can dump functions, string tables, and bytecode for deeper analysis.

Change code and rebuild (Hermes)

Ideally you should be able to modify the disassembled code (changing a comparison, or a value or whatever you need to modify) and then rebuild the bytecode and rebuild the app.

  • The original hbctool supports disassembling the bundle and building it back after changes, but historically supported only older bytecode versions. Community-maintained forks extend support to newer Hermes versions (including mid-80s–96) and are often the most practical option to patch modern RN apps.
  • The tool hermes-dec does not support rebuilding the bytecode (decompiler/disassembler only), but it’s very helpful to navigate logic and dump strings.
  • The tool hasmer aims to support both disassembly and assembly for multiple Hermes versions; assembling is still maturing but worth trying on recent bytecode.

A minimal workflow with hbctool-like assemblers:

bash
# 1) Disassemble to HASM directories
hbctool disasm assets/index.android.bundle ./hasm

# 2) Edit a guard or feature flag (example: force boolean true)
#    In the relevant .hasm, replace a LoadConstUInt8 0 with 1
#    or change a conditional jump target to bypass a check.

# 3) Reassemble into a new bundle
hbctool asm ./hasm assets/index.android.bundle

# 4) Repack the APK and resign
zip -r ../patched.apk *
# Align/sign as usual (see Android signing section in HackTricks)

Note that Hermes bytecode format is versioned and the assembler must match the exact on-disk format. If you get format errors, switch to an updated fork/alternative or rebuild the matching Hermes tooling.

Dynamic Analysis

You could try to dynamically analyze the app would be to use Frida to enable the developer mode of the React app and use react-native-debugger to attach to it. However, for this you need the source code of the app apparently. You can find more info about this in https://newsroom.bedefended.com/hooking-react-native-applications-with-frida/.

Enabling Dev Support in release with Frida (caveats)

Some apps accidentally ship classes that make Dev Support togglable. If present, you can try forcing getUseDeveloperSupport() to return true:

javascript
// frida -U -f com.target.app -l enable-dev.js
Java.perform(function(){
  try {
    var Host = Java.use('com.facebook.react.ReactNativeHost');
    Host.getUseDeveloperSupport.implementation = function(){
      return true; // force dev support
    };
    console.log('[+] Patched ReactNativeHost.getUseDeveloperSupport');
  } catch (e) {
    console.log('[-] Could not patch: ' + e);
  }
});

Warning: In properly built release builds, DevSupportManagerImpl and related debug-only classes are stripped and flipping this flag can crash the app or have no effect. When this works, you can typically expose the dev menu and attach debuggers/inspectors.

Network interception in RN apps

React Native Android typically relies on OkHttp under the hood (via the Networking native module). To intercept/observe traffic on a non-rooted device during dynamic tests:

  • Use system proxy + trust user CA or use other generic Android TLS bypass techniques.
  • RN-specific tip: if the app bundles Flipper in release by mistake (debug tooling), the Flipper Network plugin can expose requests/responses.

For generic Android interception and pinning bypass techniques refer to:

Make APK Accept CA Certificate

Objection Tutorial

When auditing third‑party modules visible in the JS bundle or native libs, check for known vulns and verify versions in package.json/yarn.lock.

  • react-native-mmkv (Android): versions prior to 2.11.0 logged the optional encryption key to Android logs. If ADB/logcat is available, secrets could be recovered. Ensure >= 2.11.0. Indicators: usage of react-native-mmkv, log statements mentioning MMKV init with encryption. CVE-2024-21668.
  • react-native-document-picker: versions < 9.1.1 were vulnerable to path traversal on Android (file selection), fixed in 9.1.1. Validate inputs and library version.

Quick checks:

bash
grep -R "react-native-mmkv" -n {index.android.bundle,*.map} 2>/dev/null || true
grep -R "react-native-document-picker" -n {index.android.bundle,*.map} 2>/dev/null || true
# If you also have the node_modules (rare on release): grep -R in package.json / yarn.lock

References

tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks