Skip to content

What was tested,
and where it stops.

Every claim below has a device, an attack and a log behind it. Where something did not hold up, it is listed here too. Detection and prevention are separate claims.

Comparison of what a rogue SDK reads without and with AppArmorX: clipboard and last location return null, the device ID is blanked, and a trust-all HTTPS verifier is rejected

Attack results

Attack results
ScenarioOutcomeWhat happened
Dependency firewallHeldBlocked 4 of 4 SDK-style scenarios (clipboard, device identifiers, last location, trust-all TLS verifier) from the app's own call sites, on device.
RepackagingHeldA release signed with a real keystore was unzipped, tampered with, re-signed with an unrelated keystore and reinstalled. Detection moved from CLEAR to DETECTED on the live app.
RootHeldA real su binary on a rooted emulator was flagged. Hidden root (Magisk/Zygisk cloaking) is not yet tested.
Direct framework calls from injected codeDid not holdWith Frida attached, a direct SSLContext.init() with a permissive trust manager bypasses the rewritten call sites. A full man-in-the-middle succeeded, even on a build that had already detected root.
Hooking, attach modeHeld (opt-in)With killOnConfirmedHooking and the watchdog enabled, the same attack was stopped before the permissive trust manager was installed. The process was gone in about a second.
Hooking, spawn mode (frida -f)Did not holdThe attacker's code runs before the library's first instruction. No in-process response can win that race.

A bug the testing found

Three native checks that read /proc/net/tcp and /sys/fs/selinux/enforce returned a clean result whenever the read itself failed. On an SELinux-enforcing device that read is denied to an app's own process, so those checks were false negatives by construction. All three now report UNAVAILABLE instead of clean. Unknown is never treated as safe.

Diagram of AppArmorX: at build time the Gradle plugin verifies policy, rewrites bytecode, bundles native engines and audits the APK; at run time a dependency firewall, 28 checks, a policy response and optional signed reports run on the device
Build-time instrumentation and run-time evidence in one picture.

Compatibility actually verified

Verified and unverified compatibility
DimensionVerifiedNot verified
AGP / Gradle / JDKAGP 9.4.1, Gradle 9.8.0, JDK 17 toolchainOther AGP majors
compileSdk34 (clean-room), 37 (sample)Below 34
minSdk29Below 29
ABIsarm64-v8a (device and emulator)x86_64 built, not run; 32-bit unsupported
DevicesPixel 7 Pro (Android 17), arm64 emulator API 35Rooted device, other OEMs, API 29-33
Host languageKotlin, Java-onlyFlutter, React Native, Unity
Honest limits

Nothing here is unbypassable. A determined attacker with kernel or hypervisor control can analyze and patch any client-side protection. These checks raise attacker cost and produce evidence; they complement server-side authorization and never replace it. No independent penetration test has been completed, and the supported device matrix is still being built.

What would close the spawn-mode gap?

Only moving the trust decision outside the attacked process, for example hardware-backed, server-verified attestation. That is a documented roadmap item, not something this release implements.