flutter_rasp 3.0.0 copy "flutter_rasp: ^3.0.0" to clipboard
flutter_rasp: ^3.0.0 copied to clipboard

A comprehensive RASP (Runtime Application Self-Protection) plugin for Flutter. Detect root, jailbreak, emulators, debuggers, hooks, repackaging, untrusted installs, VPN, SSL pinning, and more.

Flutter RASP #

pub package License: MIT Platform

A comprehensive RASP (Runtime Application Self-Protection) plugin for Flutter. Protect your app against reverse engineering, tampering, runtime attacks, and man-in-the-middle attacks with zero external SDK dependencies.


Features #

Threat Detection #

Threat Android iOS Description
Root / Jailbreak Compromised OS with full system access. Attackers can bypass app sandboxing, read private data, and inject code
Emulator / Simulator Virtual environments used to automate attacks, bypass device-bound protections, and analyze app behavior at scale
Debugger Attached debuggers (JDWP, ptrace) allow stepping through code, modifying variables at runtime, and extracting secrets
Hooks (Frida/Xposed) Instrumentation frameworks that intercept and modify function calls at runtime, bypassing security checks
Repackaging Tampered app re-signed with a different certificate. Used to inject malware, remove license checks, or steal data
Trusted Install Sideloaded apps bypass store review and integrity checks, increasing risk of running modified or malicious builds
VPN Active VPN or proxy that can intercept, inspect, and modify network traffic between the app and its servers
Developer Mode Enabled developer options and ADB expose debugging interfaces that allow unauthorized access to app internals
Device Passcode Device without screen lock. Physical access gives unrestricted access to app data and keychain entries
Secure Hardware Missing hardware-backed keystore (TEE/StrongBox, Secure Enclave). Cryptographic keys can be extracted by software attacks
Obfuscation Unobfuscated binary with readable class and symbol names, making reverse engineering and vulnerability discovery trivial
Time Spoofing Manipulated system clock used to bypass time-based logic like token expiration, trial periods, or certificate validity
Location Spoofing Fake GPS coordinates used to bypass geo-restrictions, cheat in location-based services, or commit region-locked fraud
Multi-Instance Cloned or dual-app environments that run multiple copies of the app to abuse promotions, bypass rate limits, or impersonate users
Screen Capture Blocks screenshots and screen recording to prevent leaking sensitive UI content like PINs, tokens, or personal data

SSL Certificate Pinning #

Feature Description
MitM Protection Prevents man-in-the-middle attacks by rejecting connections with certificates not matching your pinned hashes, even if signed by a trusted CA
Public Key Pinning SHA-256 of SubjectPublicKeyInfo (SPKI) — survives certificate renewals
Certificate Pinning SHA-256 of the full DER-encoded certificate
Backup Pins Multiple pins per host for key rotation
HTTP Client Compatibility dart:io, Dio (onHttpClientCreate), http (IOClient)

Getting Started #

dependencies:
  flutter_rasp: ^3.0.0
Platform Minimum Version
Android API 24 (Android 7.0)
iOS 13.0

No additional permissions required. Zero external SDK dependencies.


Usage #

Initialization #

import 'package:flutter_rasp/flutter_rasp.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await FlutterRasp.instance.initialize(
    config: const RaspConfig(
      policy: ThreatPolicy.high,
      monitoringInterval: Duration(seconds: 10),
      androidConfig: AndroidRaspConfig(
        signingCertHashes: ['AKoRuyLMM91E7lX/Zqp3u4jMmd0A7hH/Iqozu0TMVd0='],
      ),
      iosConfig: IosRaspConfig(
        teamId: 'A1B2C3D4E5',
        bundleIds: ['com.yourcompany.yourapp'],
      ),
    ),
    onThreatDetected: (threats) => debugPrint('$threats'),
    threatCallback: ThreatCallback(
      onRoot: () => navigateToBlockedScreen(),
      onVpn: () => showVpnWarning(),
    ),
  );

  runApp(const MyApp());
}

Note: At least one of onThreatDetected or threatCallback must be provided.

Platform Configuration #

AndroidsigningCertHashes expects your signing certificate fingerprint in Base64 format.

  1. Get the SHA-256 fingerprint from keytool, Google Play Console (App signing section), or Firebase Console. You will end up with a hex string like this:

    A1:2B:3C:4D:5E:6F:70:81:92:A3:B4:C5:D6:E7:F8:09:1A:2B:3C:4D:5E:6F:70:81:92:A3:B4:C5:D6:E7:F8:09
    
  2. Convert it to Base64. You can get it directly from terminal:

    keytool -list -v -keystore your-keystore.jks -alias your-alias 2>/dev/null \
      | grep SHA256 | awk '{print $2}' | tr -d ':' | xxd -r -p | base64
    

    Or use the built-in utility:

    final base64Hash = hashConverter.fromSha256toBase64(
      'A1:2B:3C:4D:5E:6F:70:81:92:A3:B4:C5:D6:E7:F8:09:1A:2B:3C:4D:5E:6F:70:81:92:A3:B4:C5:D6:E7:F8:09',
    );
    

iOS — Find your Team ID at Apple Developer AccountMembership Details.

SSL Certificate Pinning #

SSL Pinning operates independently from the threat detection system. Use SslPinningClient to create an HttpClient that rejects connections not matching your pins.

Getting the Pin Hash

Use openssl to extract the pin hash from your server. The command depends on the pinning mode you choose:

Public Key Pin (recommended — survives certificate renewals):

openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \
  | openssl x509 -pubkey -noout \
  | openssl pkey -pubin -outform DER \
  | openssl dgst -sha256 -binary \
  | base64

Certificate Pin (full certificate hash — changes on every renewal):

openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \
  | openssl x509 -outform DER \
  | openssl dgst -sha256 -binary \
  | base64

Note: Public key pins survive certificate renewals as long as the same key pair is reused. Certificate pins change every time the certificate is renewed, requiring an app update.

Basic Usage (dart:io)

import 'package:flutter_rasp/flutter_rasp.dart';

final config = SslPinningConfig(pins: {
  'api.example.com': [
    SslPin.publicKey('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX='),
  ],
});

final client = SslPinningClient.create(config);
final request = await client.getUrl(Uri.parse('https://api.example.com/data'));
final response = await request.close();

With Backup Pins (Key Rotation)

final config = SslPinningConfig(pins: {
  'api.example.com': [
    SslPin.publicKey('current_key_hash_AAAAAAAAAAAAAAAAAAAAAAAAAAA='),
    SslPin.publicKey('backup_key_hash_BBBBBBBBBBBBBBBBBBBBBBBBBBBB='),
  ],
});

With Dio

final client = SslPinningClient.create(config);

final dio = Dio()
  ..httpClientAdapter = IOHttpClientAdapter(
    onHttpClientCreate: (_) => client,
  );

With http Package

final client = SslPinningClient.create(config);
final httpClient = IOClient(client);

final response = await httpClient.get(Uri.parse('https://api.example.com/data'));

Pinning Failure Callback

final client = SslPinningClient.create(
  config,
  onPinningFailure: (host, certificate) {
    debugPrint('Pinning failed for $host');
  },
);

Pinning Modes

Mode Constructor Description
Public Key SslPin.publicKey(hash) SHA-256 of the SPKI. Recommended: survives certificate renewals
Certificate SslPin.certificate(hash) SHA-256 of the full DER-encoded certificate

Tip: Prefer publicKey mode — it survives certificate renewals as long as the key pair is reused.

Supported Stores / Distribution Methods #

The supportedStores parameter in AndroidRaspConfig controls which install sources are considered trusted.

Store / Distribution method Package name Notes
App Store (iOS) Included by default, no action needed
TestFlight (iOS) Included by default, no action needed
Google Play com.android.vending Included by default, no action needed
Huawei AppGallery com.huawei.appmarket Included by default, no action needed
Amazon Appstore com.amazon.venezia Included by default, no action needed
Samsung Galaxy Store com.sec.android.app.samsungapps Included by default, no action needed
Firebase App Distribution dev.firebase.appdistribution
Vivo App Store com.vivo.appstore Common on Vivo devices
HeyTap com.heytap.market Common on Realme and Oppo devices
Oppo App Market com.oppo.market Common on Oppo devices
GetApps com.xiaomi.mipicks Common on Xiaomi, Redmi and POCO devices

To support additional stores, add their package names:

AndroidRaspConfig(
  signingCertHashes: ['...'],
  supportedStores: [
    ...AndroidRaspConfig().supportedStores,
    'dev.firebase.appdistribution',  // Firebase App Distribution
    'com.vivo.appstore',             // Vivo App Store
    'com.heytap.market',             // HeyTap (Realme, Oppo)
    'com.oppo.market',               // Oppo App Market
    'com.xiaomi.mipicks',            // GetApps (Xiaomi, Redmi, POCO)
  ],
);

Threat Policies #

Policies control which threats terminate the app at the native level before Dart code can react.

Policy Exit Threats
ThreatPolicy.none None (report only)
ThreatPolicy.low repackaging, trustedInstall
ThreatPolicy.medium root, hook, repackaging, trustedInstall, obfuscationIssues, multiInstance
ThreatPolicy.high root, hook, repackaging, trustedInstall, debug, devicePasscode, obfuscationIssues, multiInstance, secureHardwareNotAvailable, locationSpoofing
const policy = ThreatPolicy(
  exitThreats: {Threat.root, Threat.repackaging, Threat.vpn},
);

Tip: Use ThreatPolicy.none during development.

Scans & Individual Checks #

final result = await FlutterRasp.instance.scanAll();
if (result.isCompromised) {
  debugPrint('Detected: ${result.detectedThreats}');
}

Available: isRooted(), isEmulator(), isDebugged(), isHooked(), isRepackaged(), isUntrustedInstall(), isVpnConnected(), isDeveloperMode(), isDevicePasscodeDisabled(), isSecureHardwareUnavailable(), hasObfuscationIssues(), isTimeSpoofed(), isLocationSpoofed(), isMultiInstance().

Screen Capture Protection #

await FlutterRasp.instance.blockScreenCapture(true);

Architecture #

Flutter App
    |
FlutterRasp (Singleton)             SslPinningClient (Independent)
    |                                    |
FlutterRaspPlatform (Interface)     PinValidator
    |                                |         |
MethodChannelFlutterRasp        SHA-256    SpkiExtractor
    |--- MethodChannel (commands/checks)
    |--- EventChannel  (threat stream)

    Android (Kotlin)              iOS (Swift)
    -----------------             -----------------
    DetectorRegistry              DetectorRegistry
    |-- RootDetector              |-- JailbreakDetector
    |-- EmulatorDetector          |-- SimulatorDetector
    |-- DebugDetector             |-- DebugDetector
    |-- HookDetector              |-- HookDetector
    |-- RepackagingDetector       |-- RepackagingDetector
    |-- TrustedInstallDetector    |-- TrustedInstallDetector
    |-- VpnDetector               |-- VpnDetector
    |-- DeveloperModeDetector     |-- DevicePasscodeDetector
    |-- DevicePasscodeDetector    |-- SecureHardwareDetector
    |-- SecureHardwareDetector    ScreenCaptureManager
    |-- ObfuscationDetector
    |-- TimeSpoofingDetector
    |-- LocationSpoofingDetector
    |-- MultiInstanceDetector
    ScreenCaptureManager

Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

Adding a New Detector #

  1. Create a detector class implementing ThreatDetector (Android) or ThreatDetectable (iOS)
  2. Add it to the DetectorRegistry list
  3. Add the corresponding Threat enum value in Dart

License #

This project is licensed under the MIT License - see the LICENSE file for details.

0
likes
0
points
392
downloads

Publisher

verified publisherjuandpt.dev

Weekly Downloads

A comprehensive RASP (Runtime Application Self-Protection) plugin for Flutter. Detect root, jailbreak, emulators, debuggers, hooks, repackaging, untrusted installs, VPN, SSL pinning, and more.

Homepage
Repository (GitHub)
View/report issues

Topics

#security #rasp #ssl-pinning #root-detection #flutter-plugin

License

unknown (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on flutter_rasp

Packages that implement flutter_rasp