🧪 Part 26: Asset Tampering in Flutter — Runtime Modifications and Dynamic Asset Swaps

🧪 Part 26: Asset Tampering in Flutter — Runtime Modifications and Dynamic Asset Swaps

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!🚀

Even after an app is built and running, attackers can manipulate its runtime behavior and assets loaded in memory. Using dynamic…

🔙 Check Previous Part [How Attackers Modify Your Flutter App's Assets to Inject Malicious Behavior]

Even after an app is built and running, attackers can manipulate its runtime behavior and assets loaded in memory. Using dynamic instrumentation tools like Frida, malicious apps, or modified Android frameworks, they can replace assets, alter configurations, or hijack logic in real time.

Unlike static repack attacks, runtime asset tampering doesn't require modifying the APK — it hijacks the app while it's running.

🕵️‍♂️ Real-World Runtime Tampering Scenarios

💣 Exploit 1: Replace Assets at Runtime via Frida Hooks

Attacker uses Frida to hook AssetManager.open or equivalent native method to replace asset content.

Example:

Interceptor.attach(Module.findExportByName("libflutter.so", "AssetManager_open"), {
onEnter: function(args) {
var assetPath = Memory.readUtf8String(args[1]);
if (assetPath.endsWith("config.json")) {
console.log("Hijacking config.json");
args[1] = ptr(replacementAssetPath);
}
}
});

🔥 Outcome: App loads fake config at runtime, enabling debug/premium modes, overriding real flags.

💣 Exploit 2: Tamper with Memory-Loaded Asset Content

Instead of replacing files, attackers hook Flutter's internal logic and change the buffer returned by rootBundle.loadString() or rootBundle.load().

🔥 Outcome: Malicious config injected after app is built and running — no APK modification needed.

💣 Exploit 3: Runtime Swap of JSON / HTML / UI Strings

Attacker waits for asset content to be loaded (e.g., HTML templates or labels), then:

  • Modifies them in memory
  • Alters logic/UI in WebView or UI rendering
  • Spoofs a different brand or injects tracking code

🔥 Outcome: On-screen content changes dynamically — invisible to codebase or static analyzers.

💣 Exploit 4: Asset Extraction via RAM Dump

Using tools like memfd, gdb, or frida-trace, an attacker can:

  • Dump RAM sections
  • Reconstruct decrypted/encrypted assets
  • View temporary Flutter memory maps

🔥 Outcome: Extract assets even if encrypted on disk, since memory holds them unencrypted.

📉 Real-World Impact

Risk Level: HIGH (especially on rooted or emulator devices)

🛡️ How to Fix It

✅ Fix 1: Avoid Local Assets for Critical Logic

Load config and flags from server APIs only:

final config = await http.get('/config');

Never rely on:

rootBundle.loadString('assets/config.json');

…for dynamic decision-making.

✅ Fix 2: Runtime Integrity Checks for Assets

  • Hash each asset on first load
  • Compare against expected checksum
  • Alert or terminate on mismatch

Use Dart + native hybrid logic to verify even memory-loaded content.

✅ Fix 3: Use Encrypted Assets with Native Decryption

Bundle encrypted files and decrypt only inside native code (e.g., Kotlin or C++):

final decrypted = await platform.invokeMethod('decryptAsset', {'name': 'config'});

🔥 This makes it harder for Frida or other tools to hook into decrypted memory.

✅ Fix 4: Add Frida and Hook Detection

Use native Frida detection techniques:

  • Scan loaded libraries
  • Check for known Frida symbols
  • Detect memory patching

Terminate app if signs of runtime tampering are found.

✅ Fix 5: Harden Flutter Runtime Logic

  • Minimize dynamic asset use
  • Split critical UI logic to backend-rendered APIs
  • Avoid logic that relies on local JSON or HTML rendering

❌ Anti-Patterns to Avoid

✅ Developer Checklist

  • Avoid critical logic in local assets
  • Add hash verification for loaded assets
  • Use encrypted assets and native-only decryption
  • Implement Frida/runtime hook detection
  • Restrict WebView use and sanitize inputs
  • Audit memory usage patterns for sensitive data

👀 Up Next

💥 Part 27: Miscellaneous Threats — From Stack Trace Leaks to Input Hijacking and Accessibility Abuse

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