device_integrity_check 1.0.0
device_integrity_check: ^1.0.0 copied to clipboard
Root, jailbreak, emulator and developer-mode detection for Flutter. Reports each signal separately and tells you which checks could not run, so a failed probe is never mistaken for a clean device.
Changelog #
1.0.0 #
First release under the name device_integrity_check. This is a rewrite of
safe_device_check 0.0.2+4, which was itself a fork of safe_device. The API
is new; nothing from the old package carries over.
Fixed — the package did not work #
- iOS: every check threw. The Objective-C plugin registered its method
channel as
safe_devicewhile Dart calleddevice_check, so all three real checks raisedMissingPluginExceptionon every iOS release. The plugin class registered without error, so nothing surfaced the mismatch. There is now one channel name, asserted by an on-device integration test. - Android: the module no longer compiled.
String.toLowerCase(Locale)is a compile error on current Kotlin, so the plugin could not be built with any supported toolchain. platformVersionthrew on both platforms. Dart invokedgetPlatformVersion; Android handledplatformVersion. Method names are now derived from a single source (IntegritySignal.methodName).
Fixed — detection logic #
- Emulator detection missed every current AVD. Eleven of the twelve
heuristics were built for 2019 fingerprints and matched nothing on a modern
image; the result rested entirely on one
ro.kernel.qemuread whose fallback path could not work — it passed quote characters intogetpropas part of the property name. Detection now readsro.hardware,ro.boot.qemu,ro.build.characteristicsandro.hardware.virtual_device, matches build identifiers case-insensitively on substrings, and reads properties through a fixedexecpath. - Root detection false-positived on four OEM brands. OnePlus, Motorola, Xiaomi and Oppo devices were routed to RootBeer's busybox variant, which reports rooted strictly more often — and which RootBeer documents as unsafe precisely because those manufacturers ship busybox on stock ROMs. All devices now take the same path.
- Brand matching was locale-sensitive. Lowercasing
Build.BRANDunder the user's locale broke matching under Turkish. UsesLocale.ROOT. - Two
suchecks were dead code. Both shelled out to/system/xbin/which, absent from Android for years. Replaced with direct path checks that also cover/su/bin/su,/system_ext/bin/suand Magisk locations. - iOS jailbreak detection reported every Mac as jailbroken. The unpinned
DTTJailbreakDetectiondependency resolved to 0.4.0 (2014), which checks for/bin/bashand/usr/bin/ssh— present when an iOS app runs on Apple Silicon macOS. Upstream's fix was never published, so pinning could not obtain it. Detection is now vendored, withisiOSAppOnMacand Mac Catalyst guards. - Developer-mode detection read a
Settings.Globalkey through a deprecatedSettings.Secureredirect, behind version branches unreachable atminSdk 21. ReadsSettings.Globaldirectly. - RootBeer updated to 0.1.2, adding
/system_ext/binto itssusearch and completing 16 KB page-size support for Android 15/16.
Fixed — behaviour under failure #
- Probes no longer block the UI thread. A cold root scan measured 1.8 s on the platform thread. All native probes run on a background thread and answer on the main thread.
- Failures are no longer exceptions. Probes resolve to
falseand report to anonErrorcallback. Because that hides failures by design, every failed or unsupported probe is also recorded inIntegrityReport.unavailable. - "Could not check" is distinguishable from "clean."
IntegrityReportreports which signals fired, which did not, and which could not be probed. Developer mode on iOS is nowunavailablerather than a fabricatedfalse.
Changed #
- Package renamed to
device_integrity_check; library ispackage:device_integrity_check/device_integrity_check.dart. - Static getters replaced by
DeviceIntegrity, an instance-based API behindDeviceIntegrityPlatform, so it can be faked in tests. isInstalledOnExternalStorageremoved. It readFLAG_EXTERNAL_STORAGE, which reflects an install mode modern Android no longer offers, so it was effectively a constantfalse; its fallback was unreachable.- Android package is now
io.github.wiseminds.device_integrity_check;minSdk 21,compileSdk 35, Java 17. - iOS deployment target raised to 12.0. Swift Package Manager is supported.
Added #
- Swift Package Manager support.
- 24 unit tests (20 for the plugin, 4 for the example) plus a 7-test on-device integration suite that asserts the native channel contract. All were run against a Pixel 9 Pro AVD (API 37) and an iPhone 17 Pro Max simulator (iOS 26).
- Documentation of the trust model: these are unattested client-side
heuristics, defeated by Magisk DenyList or Frida, and must not be used as an
authorization decision. See the README and
DeviceIntegrity's API docs.