Mobile RASP (Runtime Application Self-Protection) for React Native / Cordova / Ionic apps protected with JavaScript Obfuscator.
JSO's build-time obfuscation makes your shipped JS bundle unreadable. This package adds the runtime half for mobile: a guard that runs inside the app, detects root / jailbreak / Frida / emulator / signature tampering, scores the result, routes it to your SIEM, and fires a response you control.
It is the mobile counterpart to the browser jso-protector/runtime/*
modules (third-party-inventory, countermeasures, ai-script-governance)
and uses the same beacon envelope shape, so the jso-beacon-slack SIEM
adapters forward mobile threats with no adapter change.
| Source | Examples | Strength |
|---|---|---|
| JS-observable (this package, pure JS) | Frida globals, Function.prototype.toString tamper, suspicious globals, __DEV__-in-release, instrumentation timing anomaly |
Weak / evadable — a tripwire, not a guarantee |
| Native probe (host-wired module) | root, jailbreak, Magisk, unc0ver, checkra1n, Dopamine, emulator, Frida/Xposed/Substrate hooks, app-signature mismatch | Strong / authoritative — pure JS cannot read the FS or process maps |
Honest threat model. JS-only detection raises the cost of casual tampering and catches unsophisticated attaches, but a determined attacker with a native hook can hide most JS-observable signals. The assurance lives in the native probe. Ship both.
npm install https://javascriptobfuscator.com/download/jso-protector-reactnative/jso-protector-reactnative-0.2.0.tgz
This adapter is a versioned direct download and is not published in the npm registry. Pin the URL (or your mirrored copy) in the lockfile.
jso-protector and react-native are optional peer dependencies — the
pure RASP engine has zero runtime dependencies and runs anywhere
(including Node, for testing).
Already handled by jso-protector's Metro integration. This package
re-exports it for a single entry point:
// metro.config.js
const { withMetro } = require("jso-protector-reactnative");
module.exports = withMetro(baseConfig, { apiKey: process.env.JSO_API_KEY, preset: "balanced" });import { NativeModules } from "react-native";
import { createMobileGuard } from "jso-protector-reactnative";
const guard = createMobileGuard({
nativeProbe: () => NativeModules.JsoRasp.probe(), // see templates/
beaconUrl: "https://beacon.example.com/v1/jso/mobile",
intervalMs: 30000,
isReleaseBuild: !__DEV__,
isDev: __DEV__,
onThreat(report) {
if (report.verdict === "compromised") { /* gate sensitive flows */ }
},
});
guard.start();See examples/App.guard.js for a complete wiring.
Pure JS can't read the device. The strong signals come from the bundled self-contained native modules:
templates/android/JsoRaspModule.kttemplates/android/JsoRaspPackage.kttemplates/ios/JsoRasp.swift
The Android probe checks root/Magisk artifacts, su, Frida ports and
process maps, Xposed, debugger/emulator state, installer source, and an
optional SHA-256 signing-certificate pin. The iOS probe checks jailbreak
artifacts and sandbox escape, loaded Frida/Substrate images, tracing,
simulator state, enterprise provisioning, and an optional Team ID pin.
Both return a result matching the nativeProbeSchema contract:
{ platform, isRooted, isJailbroken, isDebuggable, isEmulator,
hooksDetected, signatureTampered, unofficialStore, detectedTools[] }
{
"v": 1,
"kind": "mobile-rasp",
"verdict": "compromised",
"score": 110,
"thresholds": { "suspicious": 30, "compromised": 60 },
"signals": [
{ "id": "native.rooted", "source": "native", "weight": 60, "detail": "device is rooted" },
{ "id": "native.named-tool", "source": "native", "weight": 50, "detail": "detected tool: Magisk", "tool": "Magisk" }
],
"platform": "android",
"nativeProbePresent": true
}verdict crosses to suspicious at score 30 and compromised at 60.
Weights are documented in SIGNAL_WEIGHTS and tunable per build.
For compromised devices, respondOnCompromised accepts callback,
lock, or lock-and-callback. Lock mode sets globalThis.__jsoMobileLocked
so navigation/auth/payment gates can fail closed; onCompromised(report)
provides the corresponding application hook.
npm test
25 Node tests cover the pure-data engine (every signal, the scoring thresholds, malformed input) and the guard orchestration (async probe, probe-throw capture, beacon POST, threat-hook isolation, timer lifecycle). No device required.