Engineering

Flutter app security

Otukan protects all three layers of a Flutter app: the Dart AOT snapshot, native plugins and bundled assets, validated separately on Android and iOS.

  • Flutter
  • Android
  • iOS
  • Beyond Dart obfuscation

    Otukan works with Flutter's own obfuscation and adds what it leaves out: string protection, integrity checks and runtime detection for the Dart code.

  • Three layers covered

    The Dart snapshot, the native plugin code and the bundled assets each get their own protection within your existing release.

  • Two platforms, done right

    The same Dart code ships in different containers on Android and iOS. Otukan protects and validates each build on its own terms.

What Otukan adds to your Flutter app

Protection for the code Flutter compiles, the native code it depends on and the files it ships.

  • Dart code protection

    Hardens the AOT snapshot in libapp.so and App.framework, including the string literals that Dart obfuscation leaves readable.

  • Integrity for every layer

    Checks that the Dart snapshot, engine, plugins and bundled assets are the ones you released, and responds when they are not.

  • Runtime self-protection

    Detects hooking, debugging, emulators and rooted or jailbroken devices around your Flutter app, and applies your response per flow.

  • App attestation

    Gives your backend evidence that requests come from your genuine Flutter app, complementing Play Integrity on Android and App Attest on iOS.

How it works

  1. Share your app profile

    Tell us your Flutter version, target platforms, key plugins and crash reporting setup. No binaries are needed.

  2. Set your policy

    Choose the controls and the response for each sensitive flow, separately for Android and iOS.

  3. Build as usual

    Keep flutter build and your obfuscation flags; protection fits your existing build and release pipeline.

  4. Sign and ship

    You sign each platform's build with your own keys and identities, and crash symbols stay valid.

  5. Upgrade with confidence

    Each Flutter SDK upgrade is revalidated against your protected build on both platforms.

Free for app publishers

Check your app's exposure

A passive review of your published app by an Otukan engineer. No files, no access to your systems. Findings go by email to the verified publisher.

You finish the request on the next page.

Otukan protects all three layers of a Flutter app: the Dart code compiled ahead of time into libapp.so on Android and App.framework on iOS, the native code your plugins and platform channels bring in, and the assets bundled in flutter_assets. It keeps Flutter’s own obfuscation in place and adds what that flag leaves out: string protection, integrity checks and runtime detection. Your Dart, Android and iOS crash symbols stay usable. Because the same Dart code ships in different containers on each platform, Otukan protects and validates the Android and iOS builds separately, and your policy can respond differently on each.

Code layers

Dart AOT code

In release mode, Flutter compiles Dart ahead of time into native machine code. On Android the snapshot is in libapp.so, one copy per ABI, next to the engine in libflutter.so. On iOS it is in App.framework, next to Flutter.framework. It is compiled code, not source, but it still carries symbol names and string literals such as endpoint URLs and error messages.

Flutter has its own obfuscation option, set at build time, and Otukan works alongside it:

flutter build appbundle --obfuscate --split-debug-info=build/symbols
flutter build ipa --obfuscate --split-debug-info=build/symbols

The flag renames symbols and moves debug information into the symbols directory. It does not hide strings, check integrity or detect a hostile runtime. Otukan adds those layers to the same snapshot, so an analyst faces protected strings, integrity checks and runtime detection, not only renamed symbols.

Native plugins and platform channels

Most Flutter apps depend on plugins with native code: Kotlin or Java on Android, Swift or Objective-C on iOS. Payment, identity and analytics SDKs usually arrive this way. Platform channels carry messages between Dart and this native code, and an attacker who hooks the process could observe or alter those messages. Otukan protects your own plugin code, detects hooking of the process at runtime, and tunes its checks so that third-party SDKs which inspect the app do not trip your policy. Native code that receives channel messages should still validate its inputs.

Packaged assets

Images, JSON files, fonts and other assets declared in pubspec.yaml are stored as ordinary files in flutter_assets: inside the app bundle or APK on Android, and inside App.framework on iOS. Otukan’s integrity checks cover them, so a modified asset is detected and handled by your policy.

LayerWhere it livesHow Otukan protects it
Dart codelibapp.so on Android, App.framework on iOSHardens the snapshot and its strings, alongside Dart obfuscation
Flutter enginelibflutter.so on Android, Flutter.framework on iOSCovered by integrity checks and revalidated at each Flutter upgrade
Native pluginsPlatform libraries and frameworksProtects your plugin code and tunes runtime checks for vendor SDKs
Assetsflutter_assets in the packageIntegrity-checked, so modifications are detected

Platform scope

The Dart source is shared, but the build output is not. Otukan treats the Android and iOS builds as two protected releases.

TopicAndroidiOS
ContainerApp bundle or APK with per-ABI native librariesApp bundle with embedded frameworks
SigningYour upload key; with Play App Signing, Google re-signs with the app signing keyApple-issued certificate; App Store and TestFlight builds are re-signed by Apple
Native symbolsNative debug symbols uploaded to Play Console or your crash tooldSYM files matched by UUID
Runtime signals from OtukanRoot, hooking, debugging, emulators, repackaged copiesJailbreak, hooking and swizzling, debugging, re-signed copies
AttestationPlay Integrity APIApp Attest and DeviceCheck

Platform detail is on Android app security and iOS app security. How protection fits a pipeline is covered on mobile app security integration.

Release testing

Debugging symbols and crash reporting

A protected Flutter release has three kinds of symbols: Dart symbols from --split-debug-info, native symbols for Android, and dSYMs for iOS. Otukan keeps all three valid, so your crash reporting tool reads protected releases just as it reads unprotected ones. Confirm it by forcing a crash in a protected build on each platform. Obfuscated Dart stack traces can also be read locally with flutter symbolize and the matching symbols directory.

Framework updates

Each Flutter SDK upgrade changes the engine and can change how the snapshot is laid out. Otukan revalidates protection against the new version on both platforms, and your release check stays short:

  • build baseline and protected releases from the same commit
  • run install, update, sign-in and your most sensitive flow on physical Android and iOS devices
  • confirm that crash reports symbolicate on both platforms
  • compare start-up and size against the previous release

Measurement guidance is on mobile app protection performance.

For how Flutter fits the wider protection model, return to mobile app security. If your app is already published, a free App Exposure Check reviews the public store release.

Common questions

  • Is Dart obfuscation enough to protect a Flutter app?

    It is a useful first layer with a narrow job. The obfuscate flag renames classes, functions and other symbols in the compiled Dart code. It does not hide string literals, check integrity, protect native plugin code or add runtime checks. Otukan keeps Flutter's obfuscation in place and adds those layers for Android and iOS.

  • Can a Flutter release be decompiled?

    A release build contains no Dart source, but the AOT snapshot can be analysed with reverse-engineering tools, and readable names and strings help an analyst. Otukan hardens the snapshot and its strings, so analysis becomes slower and costlier, and runtime checks report attempts to tamper with the app. Secrets still belong on your server, not in the app.

  • Do debug builds matter?

    Only if one escapes. Debug builds run Dart just in time from a kernel snapshot that carries far more information than a release build. Make sure only release builds leave your pipeline. Otukan protects the release artefact, so the build your users install is the hardened one.

Protect your Flutter app on both platforms

Tell us your Flutter version, target platforms, the native plugins you rely on and how you report crashes. We never ask for binaries, signing keys or production credentials.

Or request a technical demo