React Native Application Pentesting
A comprehensive skill for security testing React Native Android applications, covering static analysis, secret hunting, Hermes bytecode handling, and dynamic analysis.
Quick Start
# Extract bundle from APK
./scripts/extract-bundle.sh <app.apk>
# Hunt for secrets
./scripts/hunt-secrets.sh index.android.bundle
# Enable dev mode with Frida
frida -U -f <package> -l ./scripts/frida-enable-dev.js
1. Identify React Native Applications
Extract the Bundle
React Native apps contain JavaScript code in assets/index.android.bundle. Extract it:
# From APK
cp <app>.apk temp.zip
unzip -qq temp.zip -d extracted
find extracted -name "index.android.bundle"
# From AAB (Android App Bundle)
java -jar bundletool.jar build-apks \
--bundle=app-release.aab \
--output=app.apks \
--mode=universal \
--overwrite
unzip -p app.apks universal.apk > universal.apk
unzip -qq universal.apk -d extracted
Use the extraction script:
./scripts/extract-bundle.sh <app.apk> # or .aab
Verify React Native
Look for these indicators:
assets/index.android.bundleexistscom.facebook.reactclasses in the APKReactNativeHostin the code
2. Static Analysis - JavaScript Bundle
Quick Secret Hunting
Run the secret hunting script to find common credentials:
./scripts/hunt-secrets.sh index.android.bundle
This searches for:
- API endpoints and GraphQL URLs
- Firebase keys (
AIza...) - AWS access keys (
AKIA...) - Sentry DSNs
- CodePush/Expo deployment keys
- Common backend patterns
Manual Pattern Searches
# 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 keys
strings -n 6 index.android.bundle | grep -Ei "(AIza[0-9A-Za-z_-]{35}|AIzaSy[0-9A-Za-z_-]{33})"
# AWS keys
strings -n 6 index.android.bundle | grep -E "AKIA[0-9A-Z]{16}"
# CodePush/Expo
strings -n 6 index.android.bundle | grep -Ei "(CodePush|codepush:\/\/|DeploymentKey|expo-updates|expo\.io)"
# Sentry
strings -n 6 index.android.bundle | grep -Ei "(Sentry\.init|dsn\s*:|dsn\s*=)"
Webpack Bundle Analysis
If you have index.android.bundle.map, use it for unminified source. Otherwise:
- Create
index.html:
<script src="./index.android.bundle"></script>
- Open in Chrome, press
Ctrl+Shift+J(orCmd+Option+Jon macOS) - Navigate to Sources tab to see the bundle structure
Decompile Minified Bundle
Use react-native-decompiler to split the bundle into individual files for easier analysis.
3. Hermes Bytecode Analysis
Detect Hermes
file index.android.bundle
# Output: "Hermes JavaScript bytecode, version XX"
Disassemble and Decompile
Hermes bytecode requires special tools:
# hbctool (check version compatibility)
hbctool disasm ./index.android.bundle ./hasm_out
hbctool asm ./hasm_out ./index.android.bundle
# hasmer (supports newer versions)
hasmer disasm ./index.android.bundle -o hasm_out
# hermes-dec (decompiler only, no rebuild)
hbc-disassembler ./index.android.bundle /tmp/output.hasm
hbc-decompiler ./index.android.bundle /tmp/output.js
Important: Hermes bytecode is versioned. If you get format errors, try updated forks or rebuild matching Hermes tooling.
Modify and Rebuild (Hermes)
# 1. Disassemble
hbctool disasm assets/index.android.bundle ./hasm
# 2. Edit .hasm files (change comparisons, constants, feature flags)
# Example: replace LoadConstUInt8 0 with 1 to force boolean true
# 3. Reassemble
hbctool asm ./hasm assets/index.android.bundle
# 4. Repack and resign APK
zip -r ../patched.apk *
# Then align and sign (see Android signing procedures)
4. Dynamic Analysis with Frida
Enable Developer Support
Some apps have togglable dev support. Try forcing it:
frida -U -f <package> -l ./scripts/frida-enable-dev.js
Warning: In properly built release builds, debug classes are stripped and this may crash the app.
Network Interception
React Native uses OkHttp under the hood. For interception:
- Use system proxy + trust user CA
- If Flipper is accidentally bundled, use Flipper Network plugin
- Refer to Android TLS bypass techniques for pinning bypass
BLE GATT Protocol Discovery
When Hermes blocks static analysis, hook the Android BLE stack:
frida -U -f <package> -l ./scripts/frida-gatt-logger.js
This logs all Bluetooth GATT reads/writes with hex and ASCII dumps.
Hash Function Tracing
To fingerprint hash-based handshakes:
frida -U -f <package> -l ./scripts/frida-message-digest.js
This traces java.security.MessageDigest calls to capture hash inputs and outputs.
5. Known Vulnerabilities in Popular Libraries
Check for these known issues:
react-native-mmkv (CVE-2024-21668)
Versions < 2.11.0 log encryption keys to Android logs.
grep -R "react-native-mmkv" -n index.android.bundle 2>/dev/null || true
# Check logcat for MMKV encryption key logs
react-native-document-picker
Versions < 9.1.1 vulnerable to path traversal on Android.
grep -R "react-native-document-picker" -n index.android.bundle 2>/dev/null || true
General Library Checks
If you have access to package.json or yarn.lock:
grep -E "(react-native-mmkv|react-native-document-picker)" package.json yarn.lock
6. Modifying and Rebuilding
JavaScript Bundle
- Extract APK as ZIP
- Modify
index.android.bundle(or decompiled files) - Repack and resign
Hermes Bundle
- Disassemble with hbctool/hasmer
- Edit
.hasmfiles - Reassemble
- Repack and resign APK