root_jailbreak_detector 1.0.0
root_jailbreak_detector: ^1.0.0 copied to clipboard
Detects whether the device is rooted (Android) or jailbroken (iOS), so your app can react to running on a device it cannot trust.
1.0.0 #
First stable release. It is mostly a rebuild: 0.5.x no longer compiled in a current Flutter project, and the API made it easy to get a wrong answer.
Breaking #
isRooted()andisJailbreaked()are deprecated in favour ofisCompromised()andisCompromisedOrElse(), which cover both platforms. The old methods keep their platform-gated behaviour and still never throw, so existing call sites keep working; they will be removed in 2.0.0 — see the README for a migration example.- Return types are no longer nullable (
Future<bool?>→Future<bool>), so callers are not pushed into writing?? falseand quietly defaulting to "safe". isCompromised()throwsRootJailbreakDetectorExceptionwhen a check cannot run, instead of reporting the device as clean.RootJailbreakDetectorPlatformnow exposes a singleisDeviceCompromised({bool treatEmulatorAsCompromised})plusisSupported. Custom platform implementations need updating.- Minimum versions raised: Flutter 3.44, Android
minSdk24, iOS 13. The Android module andPackage.swifttrack the Flutter 3.44 plugin template, so that is the floor the package is built and tested against.
Fixed #
- Android builds now work again. The module declared no
namespaceand still carriedpackagein its manifest, which AGP 8+ rejects — the plugin failed to build in any recent Flutter project. It now uses the Gradle Kotlin DSL, AGP 9,compileSdk36 and Java 17. - The iOS sandbox check tested nothing.
canEditSystemFileswrote to a bare file name, so the path resolved against the app's working directory rather than the system root — and the answer stopped depending on whether the device was jailbroken at all. In practice that directory is not writable, so the check almost certainly returnedfalseeven on jailbroken devices; had it been writable it would have fired on every device instead. It now writes to an absolute path outside the container and removes the probe afterwards. - The native side answers
notImplementedfor unknown methods. Previously both platforms returnedfalse, which Dart could not tell apart from a genuinely clean device — soisJailbreaked()on Android andisRooted()on iOS always said "safe". - RootBeer no longer runs on the platform thread; it touches the file system and shells out
looking for
su. - Detaching from the engine shuts the scan executor down immediately instead of letting queued work run on with nowhere to report back to. A scan already in flight still answers: Flutter discards a reply aimed at a torn-down engine, whereas staying silent could leave a caller waiting on a future that never completes.
- The published archive was 13 MB of build artifacts because the package had no
.gitignore.
Added #
isCompromised()andisCompromisedOrElse(fallback)— one call covering both platforms.isCompromised()always reports failure as a failed future rather than a synchronous throw, socatchErrorcallers see it too;isCompromisedOrElse()absorbs any error, so an incomplete custom platform implementation cannot break its never-throws contract.isSupported, to tell "checked and clean" apart from "never checked".RootJailbreakDetector(treatEmulatorAsCompromised: false), to opt out of counting a simulator or emulator as compromised. On Android the exemption readsBuildproperties, which a rooted device can forge, so the README explains when this is the right lever and when gating the call onkDebugModecosts less.- Swift Package Manager support alongside CocoaPods, plus a privacy manifest.
- iOS: detection of injected libraries via the dyld image list, which catches runtime hooking that leaves no trace on disk.
- iOS: modern package managers and jailbreaks — Sileo, Zebra, Filza, libhooker, TweakInject,
and rootless staging under
/var/jb. - Android and Dart unit tests, plus an integration test that exercises the real native code.
Changed #
- A simulator or emulator is now reported as compromised by default. 0.5.4 had exempted the
iOS simulator, but that exemption rested on an assumption about what can be run there, and
it left the two platforms disagreeing — Android emulators running a test-keys image were
already being flagged.
RootJailbreakDetector(treatEmulatorAsCompromised: false)opts out on both platforms; the README explains why gating the call onkDebugModeis usually the better trade. - RootBeer 0.1.0 → 0.1.1.
- The iOS
UIDevice.isJailBrokenextension is gone. It waspublic, so it leaked ontoUIDevicefor every app that imported the plugin. - The podspec carries real metadata instead of the
A new Flutter plugin projecttemplate placeholders. - The example app was rebuilt on the current Flutter template; the old one could not build.
- The analyzer runs with
strict-casts,strict-inferenceandstrict-raw-types, and every public member is required to carry documentation.
0.5.4 #
- iOS simulator control fix
0.5.3 #
- Small fixes
0.5.2 #
- Documentation is provided.
0.5.1 #
- Desciption is changed.
0.5.0 #
- Root and Jailbreak control enabled, published.