🧬 Part 8: Runtime Code Injection in Flutter — How Frida Hooks Can Modify Your App on the Fly

🧬 Part 8: Runtime Code Injection in Flutter — How Frida Hooks Can Modify Your App on the Fly

FlutterPulse

This article was translated specially for the channel FlutterPulseYou'll find lots of interesting things related to Flutter on this channel. Don't hesitate to subscribe!🚀

What if an attacker could change your app's behavior while it's running?
 Without modifying the source code?
 Without even touching the…

đź”™ Check Previous Part [Deep Link Hijacking in Flutter]

What if an attacker could change your app's behavior while it's running?
Without modifying the source code?
Without even touching the APK?

Welcome to the world of runtime code injection — where tools like Frida, Xposed, and Objection allow attackers to intercept or override Dart and native plugin methods at runtime. Flutter, though compiled ahead-of-time (AOT), is not immune.

This article shows how attackers perform live memory manipulation of Flutter apps and what developers must do to mitigate this critical risk.

🔥 What's the Problem?

When your app is running on a rooted device, attackers can:

  • Attach dynamic instrumentation tools like Frida
  • Override Dart variables, flags, and methods
  • Hook into native plugins written in Java/Kotlin/Swift
  • Extract sensitive data from memory
  • Bypass authentication or licensing logic

This requires no APK modification — only a running process.

🕵️‍♂️ Real-World Exploit Scenarios

đź’Ł Exploit 1: Override In-App Purchase Check

Suppose your Flutter code contains:

if (isPremiumUser) {
showPremiumContent();
}

And isPremiumUser is stored in Dart memory as a simple bool. An attacker can:

// Frida script
Java.perform(function () {
var Boolean = Java.use('java.lang.Boolean');
Boolean.valueOf.overload('boolean').implementation = function (val) {
console.log("Forcing premium");
return Boolean.TRUE;
};
});

Result: App always treats user as premium — no payment needed.

đź’Ł Exploit 2: Hook Native Flutter Plugins

Plugins like flutter_secure_storage, in_app_purchase, or device_info_plus rely on platform code.

Frida can hook native methods like this:

Java.perform(function () {
var SecureStorage = Java.use("com.it_nomads.flutter.SecureStoragePlugin");
SecureStorage.getItem.implementation = function (key) {
console.log("Intercepted getItem: " + key);
return "fake_token";
};
});

Impact: Token theft, bypassing fingerprint checks, or fake purchases.

đź’Ł Exploit 3: Inject Data into Native Memory

Attackers can use Frida or Xposed to inject code that:

  • Fakes biometric auth results
  • Changes API responses in memory
  • Prevents crash on invalid license keys
  • Replaces entire widget tree via hooks

📉 Real-World Impact

Risk Level: CRITICAL

🛡️ How to Fix It

While complete prevention is difficult on rooted devices, you can harden your app against runtime manipulation.

âś… Fix 1: Use Native Integrity Checks

Use the root_check or custom plugins to detect rooting/emulation:

bool isRooted = await RootCheck.isDeviceRooted;
if (isRooted) {
exitApp(); // or limit features
}

âś… Fix 2: Obfuscate Your Dart Code

Flutter AOT compiles Dart to native, but symbol names can be preserved. Use:

flutter build apk --release --obfuscate --split-debug-info=build/symbols/

This makes memory inspection and Frida hooking significantly harder.

âś… Fix 3: Secure Critical Logic Server-Side

Never trust local flags like isAdmin = true or canAccessFeature = true.

Instead:

  • Validate roles on backend
  • Use signed tokens (JWT with claims)
  • Don't rely on client to authorize itself

âś… Fix 4: Implement Anti-Debugging and Frida Detection

Use native methods to detect process injection:

public static boolean isFridaPresent() {
try {
String[] suspicious = { "frida", "gum-js-loop", "gadget" };
for (String name : suspicious) {
if (Debug.isDebuggerConnected() || nameInProcMaps(name)) {
return true;
}
}
} catch (Exception e) {}
return false;
}

Or use community-built libraries like fridasec.

âś… Fix 5: Encrypt and Limit In-Memory Sensitive Data

Instead of storing tokens in memory, use:

  • flutter_secure_storage + native hardware encryption
  • Token expiration with short TTL
  • Remove tokens from memory immediately after use

❌ Anti-Patterns to Avoid

âś… Developer Checklist

  • Enable Dart code obfuscation with --split-debug-info
  • Use flutter_secure_storage and avoid globals for sensitive data
  • Detect root, emulator, and Frida injection
  • Validate auth and roles via backend, not local flags
  • Encrypt sensitive logic and use short-lived tokens
  • Implement crash reporting to detect hook-based tampering

đź‘€ Up Next

🧱 Part 9: Hardcoded API Keys in Flutter — How Secrets Leak Through APK Decompilation

Thank you for reading this article

If I missed something or made an error, please let me know in the comments. I'm always eager to learn and improve.

Give a clap 👏 if you found this article helpful.

Report Page