tomato_sentinel 1.0.1 copy "tomato_sentinel: ^1.0.1" to clipboard
tomato_sentinel: ^1.0.1 copied to clipboard

Production-grade Flutter security SDK providing SSL pinning, root/jailbreak detection, anti-tampering, Play Integrity, and App Attest support.

Tomato Sentinel 🍅 #

pub package License

Production-grade Flutter security SDK providing comprehensive mobile application security for Android and iOS. Built for banking-grade applications with OWASP MASVS L2 compliance.

Features #

🔐 SSL Public Key Pinning #

  • SPKI SHA-256 certificate pinning
  • Embedded backup pins
  • Dynamic pin updates via signed remote config
  • Direct integration with Dio HTTP client
  • Prevents MITM attacks

🛡️ Runtime Security #

  • Root/Jailbreak Detection - Multi-layered detection
  • Emulator Detection - Identifies simulator environments
  • Frida Detection - Detects hooking frameworks (Frida, Xposed, Cydia Substrate)
  • Tamper Detection - Binary integrity verification
  • Debugger Detection - Runtime debugging detection

✅ Device Integrity #

  • Play Integrity API (Android) - Google's device attestation
  • App Attest (iOS) - Apple's app integrity verification
  • DeviceCheck support

🔄 Remote Configuration #

  • Signed remote config with RSA-4096/ECDSA P-384
  • Dynamic security policy updates
  • Replay attack prevention
  • Automatic configuration validation

🏗️ Architecture #

  • Clean, modular architecture
  • Riverpod state management support
  • Async initialization
  • TOCTOU prevention
  • Fail-closed security model
  • Production-ready obfuscation support

OWASP MASVS Compliance #

This SDK implements security controls aligned with OWASP Mobile Application Security Verification Standard (MASVS) Level 2:

Control Description Implementation
MSTG-NETWORK-4 SSL Pinning ✅ SPKI SHA-256 pinning
MSTG-RESILIENCE-1 Root/Jailbreak Detection ✅ Multi-method detection
MSTG-RESILIENCE-2 Debugger Detection ✅ Runtime checks
MSTG-RESILIENCE-3 Tamper Detection ✅ Signature verification
MSTG-RESILIENCE-4 Hook Detection ✅ Frida/Xposed detection
MSTG-RESILIENCE-5 Emulator Detection ✅ Environment checks

Installation #

Add to your pubspec.yaml:

dependencies:
  tomato_sentinel: ^1.0.0

Quick Start #

1. Initialize the SDK #

import 'package:tomato_sentinel/tomato_sentinel.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // Configure SSL pinning
  final pinConfig = PinConfigurationBuilder()
      .domain('api.example.com')
      .addPin('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') // Primary
      .addPin('BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=') // Backup
      .includeSubdomains(true)
      .build();

  // Production configuration
  final config = TomatoSentinelConfig.production(
    pinConfigurations: {'api.example.com': pinConfig},
    remoteConfigUrl: 'https://api.example.com/security/config',
    remoteConfigPublicKey: 'YOUR_PUBLIC_KEY_PEM',
    playIntegrityCloudProjectNumber: '123456789',
    appAttestKeyId: 'com.example.app.attest',
    onSecurityEvent: (event) {
      print('Security Event: ${event.type}');
    },
  );

  await TomatoSentinel.initialize(config);
  
  runApp(MyApp());
}

2. Check Security Status #

// Get current security status
final status = await TomatoSentinel.instance.getSecurityStatus();

if (!status.isDeviceSecure) {
  // Handle security threats
  for (final threat in status.allThreats) {
    print('Threat: ${threat.type} - ${threat.description}');
  }
}

// Check specific threats
final isRooted = await TomatoSentinel.instance.isDeviceRooted();
final isEmulator = await TomatoSentinel.instance.isEmulator();
final isHooked = await TomatoSentinel.instance.isHooked();

3. Secure HTTP Client #

import 'package:tomato_sentinel/tomato_sentinel.dart';

// Create secure Dio client with SSL pinning
final client = SecureDioClient.create(config);

// Make requests - pinning is automatic
final response = await client.get('https://api.example.com/data');

4. Riverpod Integration #

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:tomato_sentinel/tomato_sentinel.dart';

class MyApp extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final securityStatus = ref.watch(securityStatusProvider);
    
    return securityStatus.when(
      data: (status) => status.isDeviceSecure 
          ? SecureApp() 
          : SecurityWarningScreen(),
      loading: () => LoadingScreen(),
      error: (error, stack) => ErrorScreen(error),
    );
  }
}

Generating SSL Pins #

To generate SPKI SHA-256 pins for your certificates:

Using OpenSSL #

# Extract SPKI from certificate
openssl x509 -in certificate.crt -pubkey -noout | \
openssl pkey -pubin -outform der | \
openssl dgst -sha256 -binary | \
openssl enc -base64

Using Online Tools #

  1. Visit your API endpoint in Chrome
  2. Click the lock icon → Certificate
  3. Use tools like SSL Labs to get the pin

Important: Always Include Backup Pins #

final pinConfig = PinConfigurationBuilder()
    .domain('api.example.com')
    .addPin('PRIMARY_PIN_HERE')      // Current certificate
    .addPin('BACKUP_PIN_HERE')       // Backup certificate
    .addPin('ROOT_CA_PIN_HERE')      // Root CA (optional)
    .build();

Remote Configuration #

Server-Side Setup #

  1. Generate RSA-4096 key pair:
# Generate private key
openssl genrsa -out private_key.pem 4096

# Extract public key
openssl rsa -in private_key.pem -pubout -out public_key.pem
  1. Create signed configuration:
{
  "version": 2,
  "createdAt": "2026-05-08T10:00:00Z",
  "expiresAt": "2026-08-08T10:00:00Z",
  "nonce": "RANDOM_NONCE_HERE",
  "pinConfigurations": {
    "api.example.com": {
      "domain": "api.example.com",
      "pins": ["PIN1", "PIN2"],
      "includeSubdomains": true
    }
  },
  "securityPolicy": {
    "enforceRootDetection": true,
    "enforceEmulatorDetection": true,
    "enforceHookDetection": true,
    "enforceTamperDetection": true,
    "minimumAppVersion": 100
  },
  "signature": "BASE64_SIGNATURE_HERE"
}
  1. Sign the configuration:
# Create signature payload
echo -n "2|2026-05-08T10:00:00Z|2026-08-08T10:00:00Z|NONCE" | \
openssl dgst -sha256 -sign private_key.pem | \
openssl enc -base64

Android Setup #

build.gradle #

android {
    compileSdkVersion 34
    
    defaultConfig {
        minSdkVersion 24
        targetSdkVersion 34
    }
    
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    // Play Integrity API
    implementation 'com.google.android.play:integrity:1.3.0'
}

ProGuard Rules #

# Tomato Sentinel
-keep class ts.sun.tomato_sentinel.** { *; }
-keep class ts.sun.tomato_sentinel.security.** { *; }

# Play Integrity
-keep class com.google.android.play.core.integrity.** { *; }

iOS Setup #

Podfile #

platform :ios, '13.0'

target 'Runner' do
  use_frameworks!
  use_modular_headers!

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end

Info.plist #

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <false/>
</dict>

Security Best Practices #

1. Fail-Closed Policy #

Always use fail-closed in production:

final config = TomatoSentinelConfig.production(
  failClosed: true,  // App terminates on critical threats
  enforceInDebugMode: true,
);

2. Multiple Pins #

Always configure at least 2 pins:

.addPin('CURRENT_CERT_PIN')   // Primary
.addPin('BACKUP_CERT_PIN')    // Backup for rotation

3. Pin Expiration #

Set expiration dates:

.expiresAt(DateTime.now().add(Duration(days: 90)))

4. Security Event Monitoring #

Monitor all security events:

onSecurityEvent: (event) {
  // Log to your analytics/monitoring service
  analytics.logSecurityEvent(
    type: event.type.name,
    message: event.message,
    metadata: event.metadata,
  );
}

5. Obfuscation #

Enable code obfuscation:

flutter build apk --obfuscate --split-debug-info=build/debug-info
flutter build ios --obfuscate --split-debug-info=build/debug-info

Threat Model #

Threats Mitigated #

  1. MITM Attacks - SSL pinning prevents certificate substitution
  2. Root/Jailbreak Exploitation - Detects compromised devices
  3. Runtime Manipulation - Detects Frida, Xposed, debuggers
  4. Emulator-Based Attacks - Identifies non-genuine devices
  5. Binary Tampering - Signature verification
  6. Replay Attacks - Nonce-based remote config

Attack Surface #

  • Network layer (SSL/TLS)
  • Runtime environment
  • Binary integrity
  • Device integrity

Performance #

  • Initialization: < 100ms
  • Security checks: < 50ms (cached)
  • SSL pinning: No measurable overhead
  • Memory footprint: < 5MB

Limitations #

  1. Root/Jailbreak Detection: Not 100% foolproof - determined attackers can bypass
  2. Obfuscation: Provides security through obscurity, not cryptographic security
  3. Play Integrity: Requires Google Play Services
  4. App Attest: Requires iOS 14+ and Apple Developer Program

Development Mode #

For development, use relaxed configuration:

final config = TomatoSentinelConfig.development(
  pinConfigurations: {}, // No pinning in dev
);

⚠️ WARNING: Never ship development configuration to production!

Testing #

void main() {
  test('Security initialization', () async {
    final config = TomatoSentinelConfig.development();
    await TomatoSentinel.initialize(config);
    expect(TomatoSentinel.isInitialized, true);
  });
}

Troubleshooting #

SSL Pinning Failures #

  1. Verify pin format (Base64, 44 characters)
  2. Check certificate chain
  3. Ensure pins match current certificate
  4. Verify domain configuration

Root Detection False Positives #

Some legitimate tools may trigger detection:

  • Development tools
  • Accessibility services
  • Custom ROMs

Adjust sensitivity in configuration.

Contributing #

Contributions welcome! Please read CONTRIBUTING.md.

License #

MIT License - see LICENSE file.

Support #

Acknowledgments #

  • OWASP Mobile Security Project
  • Flutter Security Community
  • Contributors and testers

⚠️ Security Notice: This SDK provides defense-in-depth security controls but is not a silver bullet. Always follow secure development practices and conduct regular security audits.

Built with ❤️ for secure Flutter applications

1
likes
135
points
86
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Production-grade Flutter security SDK providing SSL pinning, root/jailbreak detection, anti-tampering, Play Integrity, and App Attest support.

Repository (GitHub)
View/report issues

Topics

#security #ssl-pinning #root-detection #jailbreak-detection #mobile-security

License

BSD-3-Clause (license)

Dependencies

convert, crypto, dio, flutter, flutter_riverpod, meta, plugin_platform_interface, riverpod

More

Packages that depend on tomato_sentinel

Packages that implement tomato_sentinel