How to Detect Root on Flutter

Need to secure your Flutter app against rooted devices? Start here.

If your Flutter app runs on a rooted Android phone, attackers can tamper with it, inject malicious code, or bypass security checks. Root detection helps you protect sensitive data and maintain app integrity.

What is rooting?

Rooting removes Android’s built-in restrictions and grants privileged (root) access to the device. With root access, users (or attackers) can:

  • Modify your app’s code or memory.

  • Inject malicious libraries using tools like Magisk or Xposed.

  • Bypass key protections such as SSL pinning.

It’s like removing the lock from your front door — anyone can walk in, change things, or steal information.

How common is rooting?

About 0.03% of Android devices are rooted. That may sound small, but at global scale it still means millions of devices. If your app handles sensitive data, you can’t ignore this risk.

Number of Rooted Devices (source: Talsec)

How to detect rooted device?

Attackers use advanced tools like Magisk and Shamiko to hide root access. Simple checks like

  • Detection of suspicious binaries

  • Detection of suspicious processes

  • Check for elevated permissions

may catch older roots, but they quickly become outdated. Building your own detection logic is time-consuming and hard to maintain. Basic techniques involve.

While building your own solution offers control, it’s not recommended due to the time, effort, and expertise required to keep up. A better option is to use an actively maintained SDK that evolves with new attack methods.

DIY Coding Guide

You can implement yourself simple root detection like this:

import 'dart:io';

Future<bool> detectSuBinary() async {
  // Common paths where the 'su' binary may exist on rooted devices
  final suPaths = [
    '/system/bin/su',
    '/system/xbin/su',
    '/sbin/su',
    '/system/su',
    '/system/bin/.ext/su',
    '/system/usr/we-need-root/su',
    '/system/app/Superuser.apk'
  ];

  for (var path in suPaths) {
    try {
      final file = File(path);
      if (await file.exists()) {
        print("Potential root detected: su binary found at $path");
        return true;
      }
    } catch (_) {
      // Ignore errors for inaccessible paths
    }
  }
  return false;
}

Use freeRASP (free library by Talsec)

With freeRASP, the root detection utilizes hundreds of advanced checks, offering robust detection even with hiding methods applied.

  • Strong detection (including Magisk 29+, Hide My Applist and Shamiko).

  • Active maintenance with frequent updates.

  • 14 additional detections : app integrity, Frida (runtime injection), hooking, emulator use, debugging, screenshots, etc.

  • Used by 6000+ apps; #1 Mobile RASP SDK by popularity (link)

Integration example

Add the freeRASP in your project, focus on implementing the following callback:

final threatCallback = ThreatCallback(
      onPrivilegedAccess: () => print('Root/Jailbreak detected'),
      ...
);

Talsec.attachListener(...);
Talsec.instance.start(...);

Key Takeaway

Rooted devices grant attackers privileged access, allowing them to tamper with apps, inject malicious code, or bypass critical protections like SSL pinning. Detection doesn’t have to be DIY or error-prone—simple checks for su binaries or elevated permissions are easily bypassed. Tools like freeRASP provide reliable, continuously updated detection with hundreds of advanced checks, letting you respond proactively to root threats and maintain app integrity.

👉 If you want root detection plus jailbreak, Frida, emulator, debugging, screenshot, and tampering protection in one free package, start with freeRASP by Talsec.

Last updated

Was this helpful?