flutter_defender

Defense-in-depth security controls for sensitive Flutter screens on Android and iOS.

Use flutter_defender to conceal guarded content, enforce lifecycle timeouts, detect common device risks, and request server-verifiable platform attestation. It is designed for finance, healthcare, identity, enterprise, and other apps that handle sensitive data.

Features

Capability Android iOS
Screenshot and recent-app protection FLAG_SECURE Secure native surface
Capture and focus-loss handling Screenshot and lifecycle events Screenshot, live capture, and immediate concealment
Guarded screens and scoped content Yes Yes
OTP and authenticated-session timeouts Yes Yes
Root / jailbreak, proxy / VPN, and RASP signals Yes Yes
Release emulator / simulator policy Yes Yes
Server-verifiable integrity Play Integrity App Attest
Optional secure storage Keystore-backed Keychain-backed

flutter_defender is a client-side security layer, not an authorization system. Runtime signals can be bypassed on a controlled device. Sensitive operations must still be authorized by a trusted backend; see Platform attestation.

Installation

dependencies:
  flutter_defender: ^0.7.0

Then run:

flutter pub get

Quick start

Initialize the package once before runApp:

import 'package:flutter/widgets.dart';
import 'package:flutter_defender/flutter_defender.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await FlutterDefender.instance.init(
    otpBackgroundTimeoutSeconds: 60,
    authenticatedBackgroundTimeoutSeconds: 120,
    onLogoutRequested: () {
      // Clear the session and return to a safe route.
    },
  );

  runApp(const MyApp());
}

Wrap sensitive UI directly—no route observer is required:

class StatementPage extends StatelessWidget {
  const StatementPage({super.key});

  @override
  Widget build(BuildContext context) {
    return const FlutterDefenderSensitiveGuard(
      child: StatementView(),
    );
  }
}

Choose the guard that matches the content:

Guard Use it for
FlutterDefenderSensitiveGuard A complete screen that should block on policy violations
FlutterDefenderSecureContentGuard A sensitive region while the rest of the screen remains usable
FlutterDefenderOtpGuard An OTP route that should close after its background timeout

Both sensitive-content guards accept placeholderBuilder for a custom concealment state. Native screenshot protection applies to the Android window or shared iOS Flutter surface, even when only one Dart region is replaced.

Tell the package when authentication changes:

FlutterDefender.instance.setAuthenticated(true);  // After login.
FlutterDefender.instance.setAuthenticated(false); // During logout.

Configuration

Common init options:

Option Purpose Default
otpBackgroundTimeoutSeconds Close an active OTP route after backgrounding 60
authenticatedBackgroundTimeoutSeconds Request logout after an authenticated background timeout 120
enableEmulatorDetectionRelease Block guarded release builds on emulators or simulators true
enableRootDetection Enable root or jailbreak indicators Release: on; debug/profile: off
enableProxyVpnDetection Block on proxy or VPN signals false
enableRaspDetection Block on debugger or hooking signals false
enableSecureStorageHelper Enable the optional storage API false
failClosedOnPlatformError Keep guarded content blocked after native protection errors false

Callbacks such as onRootDetected, onProxyOrVpnDetected, and onTamperingDetected let the host app record or react to policy events. UI can be customized with blockingScreenBuilder, uiTheme, locale, and message resolvers.

For every option and its behavior, see the API reference.

Platform setup

Android release launch guard

Guarded widgets can block an emulator after Flutter starts. For stricter release-only enforcement before Flutter starts, configure ReleaseEmulatorGuardActivity as the app's only launcher activity.

This manifest edit must leave exactly one MAIN/LAUNCHER activity. Do not add a second .MainActivity declaration—the merged manifest can otherwise produce two app icons or leave a bypassable exported activity.

Follow the complete Android release launch guard setup.

Platform attestation

Use FlutterDefenderAttestation when a backend needs stronger evidence for a sensitive operation:

  • Android: Play Integrity standard tokens.
  • iOS: App Attest key enrollment and assertions.
  • Backend: verify the artifact, request binding, app identity, freshness, and platform verdict before authorizing the operation.

Follow the complete platform attestation guide.

Optional security layers

Root/jailbreak detection, proxy/VPN detection, RASP, request signing, and secure storage are opt-in or policy-driven layers. Their results have different trust boundaries and failure behavior.

Read Security layers and limitations before enabling them in production.

Blocking UI

The built-in blocking UI is full-screen and absorbs interaction. You may replace its visible content while the package retains the modal barrier:

await FlutterDefender.instance.init(
  blockingScreenBuilder: (message) {
    return Center(child: Text(message));
  },
);

Localization

Register the package delegates in the host app:

MaterialApp(
  localizationsDelegates: const [
    ...FlutterDefenderLocalizations.localizationsDelegates,
  ],
  supportedLocales: mergeFlutterDefenderSupportedLocales(
    const [Locale('en')],
  ),
);

Built-in locales: English, Arabic, French, and Spanish.

Example

The example/ app demonstrates guards, lifecycle timeouts, policy profiles, UI customization, advanced signals, and manual platform checks.

cd example
flutter run

Documentation

License

Apache-2.0