root_jailbreak_check 0.0.1
root_jailbreak_check: ^0.0.1 copied to clipboard
On-device root (Android) and jailbreak (iOS) detection. Pure Kotlin/Swift heuristics, no bundled native binaries, no network calls, no third-party services.
root_jailbreak_check #
On-device root (Android) and jailbreak (iOS) detection for Flutter.
Status: standalone, general-purpose package — not tied to any specific app. Not yet published to pub.flutter-io.cn; until then, depend on it directly via git in
pubspec.yaml:dependencies: root_jailbreak_check: git: url: https://github.com/yess-wee/root_jailbreak_check.git
- No bundled native binaries — detection is plain Kotlin (Android) and
Swift (iOS), so there's nothing to go out of alignment with Android's
16 KB page-size requirement, and no prebuilt
.so/framework to trust. - No network calls, no third-party SDK, no telemetry. Everything runs locally on the device; nothing about the check or its result ever leaves the app.
- Fails open. If detection itself errors out, the result is
false— a bug in a heuristic should never lock out a legitimate user.
What it checks #
Android — signing build tags (test-keys), presence of common su
binaries, known root-management packages (Magisk, SuperSU, KingRoot, etc.),
whether su is executable on PATH, and whether /system is writable.
iOS — known jailbreak-tool paths (Cydia, Sileo, MobileSubstrate, etc.),
whether the app can write outside its sandbox, and the DYLD_INSERT_LIBRARIES
environment variable (used by dynamic-injection tools like Frida).
These are standard, well-documented heuristics — like any on-device check, they raise the bar rather than guarantee detection against a sufficiently determined attacker.
Usage #
import 'package:root_jailbreak_check/root_jailbreak_check.dart';
final compromised = await RootJailbreakCheck.isJailbroken();
if (compromised) {
// show a block/warning screen, restrict sensitive actions, etc.
}
Testing on a clean device #
Root/jailbreak detection is naturally hard to positive-test without an actual rooted/jailbroken device. During development you can force a positive result at the call site with a debug-only flag in your own app, e.g.:
final compromised = kReleaseMode
? await RootJailbreakCheck.isJailbroken()
: (const bool.fromEnvironment('FORCE_COMPROMISED') ||
await RootJailbreakCheck.isJailbroken());
then run with --dart-define=FORCE_COMPROMISED=true.