You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
158 lines
5.9 KiB
Dart
158 lines
5.9 KiB
Dart
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:freerasp/freerasp.dart';
|
|
import 'package:hmg_patient_app_new/core/app_state.dart';
|
|
import 'package:hmg_patient_app_new/core/talsec_config.dart';
|
|
import 'package:hmg_patient_app_new/services/logger_service.dart';
|
|
|
|
/// Enum to categorize threat severity levels
|
|
enum ThreatSeverity {
|
|
critical, // Block app usage
|
|
warning, // Log only, don't block
|
|
}
|
|
|
|
/// Model to track threat details
|
|
class ThreatEvent {
|
|
final String threatType;
|
|
final ThreatSeverity severity;
|
|
final DateTime timestamp;
|
|
final String? additionalInfo;
|
|
|
|
ThreatEvent({
|
|
required this.threatType,
|
|
required this.severity,
|
|
this.additionalInfo,
|
|
}) : timestamp = DateTime.now();
|
|
}
|
|
|
|
/// Callback type for critical threat detection
|
|
typedef OnCriticalThreatDetected = void Function();
|
|
|
|
/// Abstract class defining the security service interface
|
|
abstract class SecurityService {
|
|
/// Initialize and start the security monitoring
|
|
Future<void> initialize();
|
|
|
|
/// Check if device is currently safe
|
|
bool get isSafeDevice;
|
|
|
|
/// Get list of detected threats
|
|
List<ThreatEvent> get detectedThreats;
|
|
|
|
/// Set callback for when critical threat is detected
|
|
void setOnCriticalThreatCallback(OnCriticalThreatDetected callback);
|
|
}
|
|
|
|
/// Implementation of SecurityService using Talsec (freeRASP)
|
|
class SecurityServiceImpl implements SecurityService {
|
|
final AppState appState;
|
|
final LoggerService loggerService;
|
|
|
|
final List<ThreatEvent> _detectedThreats = [];
|
|
bool _isInitialized = false;
|
|
OnCriticalThreatDetected? _onCriticalThreatCallback;
|
|
|
|
SecurityServiceImpl({
|
|
required this.appState,
|
|
required this.loggerService,
|
|
});
|
|
|
|
@override
|
|
bool get isSafeDevice => appState.isSafeDevice;
|
|
|
|
@override
|
|
List<ThreatEvent> get detectedThreats => List.unmodifiable(_detectedThreats);
|
|
|
|
@override
|
|
Future<void> initialize() async {
|
|
if (_isInitialized) {
|
|
loggerService.logInfo('SecurityService already initialized');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
loggerService.logInfo('Initializing SecurityService with Talsec');
|
|
|
|
// Start the RASP engine
|
|
await Talsec.instance.start(talsecConfig);
|
|
|
|
// Setup threat callbacks
|
|
final callback = ThreatCallback(
|
|
onAppIntegrity: () => _handleThreat('App Integrity', ThreatSeverity.critical),
|
|
onObfuscationIssues: () => _handleThreat('Obfuscation Issues', ThreatSeverity.warning),
|
|
onDebug: () => _handleThreat('Debug Mode', ThreatSeverity.critical),
|
|
onDeviceBinding: () => _handleThreat('Device Binding', ThreatSeverity.critical),
|
|
onDeviceID: () => _handleThreat('Device ID Mismatch', ThreatSeverity.critical),
|
|
onHooks: () => _handleThreat('Hooks Detected', ThreatSeverity.critical),
|
|
onPasscode: () => _handleThreat('Passcode Not Set', ThreatSeverity.warning),
|
|
onPrivilegedAccess: () => _handleThreat('Privileged Access (Root/Jailbreak)', ThreatSeverity.critical),
|
|
onSecureHardwareNotAvailable: () => _handleThreat('Secure Hardware Not Available', ThreatSeverity.warning),
|
|
onSimulator: () => _handleThreat('Simulator/Emulator Detected', ThreatSeverity.critical),
|
|
onSystemVPN: () => _handleThreat('System VPN Active', ThreatSeverity.warning),
|
|
onDevMode: () => _handleThreat('Developer Mode', ThreatSeverity.warning),
|
|
onADBEnabled: () => _handleThreat('USB Debugging Enabled', ThreatSeverity.warning),
|
|
onUnofficialStore: () => _handleThreat('Unofficial Store Installation', ThreatSeverity.critical),
|
|
onScreenshot: () => _handleThreat('Screenshot Detected', ThreatSeverity.warning),
|
|
onScreenRecording: () => _handleThreat('Screen Recording Active', ThreatSeverity.warning),
|
|
onMultiInstance: () => _handleThreat('Multiple Instances', ThreatSeverity.warning),
|
|
onLocationSpoofing: () => _handleThreat('Location Spoofing', ThreatSeverity.warning),
|
|
onTimeSpoofing: () => _handleThreat('Time Spoofing', ThreatSeverity.warning),
|
|
onAutomation: () => _handleThreat('Automation Detected', ThreatSeverity.warning),
|
|
onBootloader: () => _handleThreat('Unlocked Bootloader', ThreatSeverity.critical),
|
|
onMalware: (suspiciousApps) => _handleThreat('Malware/Suspicious Apps', ThreatSeverity.critical, additionalInfo: suspiciousApps.toString()),
|
|
);
|
|
|
|
Talsec.instance.attachListener(callback);
|
|
|
|
_isInitialized = true;
|
|
loggerService.logInfo('SecurityService initialized successfully');
|
|
} catch (e) {
|
|
loggerService.logError('Failed to initialize SecurityService: $e');
|
|
if (!kDebugMode) {
|
|
FirebaseCrashlytics.instance.recordError(
|
|
e,
|
|
StackTrace.current,
|
|
reason: 'SecurityService initialization failed',
|
|
fatal: false,
|
|
);
|
|
}
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
@override
|
|
void setOnCriticalThreatCallback(OnCriticalThreatDetected callback) {
|
|
_onCriticalThreatCallback = callback;
|
|
loggerService.logInfo('Critical threat callback registered');
|
|
}
|
|
|
|
/// Handle detected threats with appropriate severity
|
|
void _handleThreat(String threatType, ThreatSeverity severity, {String? additionalInfo}) {
|
|
final threat = ThreatEvent(
|
|
threatType: threatType,
|
|
severity: severity,
|
|
additionalInfo: additionalInfo,
|
|
);
|
|
|
|
_detectedThreats.add(threat);
|
|
|
|
// Log to console
|
|
if (severity == ThreatSeverity.critical) {
|
|
loggerService.logError('🔴 CRITICAL THREAT: $threatType ${additionalInfo != null ? "- $additionalInfo" : ""}');
|
|
} else {
|
|
loggerService.logInfo('⚠️ WARNING: $threatType ${additionalInfo != null ? "- $additionalInfo" : ""}');
|
|
}
|
|
|
|
// Block app if critical threat
|
|
if (severity == ThreatSeverity.critical) {
|
|
appState.setIsSafeDevice = false;
|
|
loggerService.logError('Device marked as UNSAFE due to: $threatType');
|
|
|
|
// Trigger callback to navigate to unsafe device page
|
|
if (_onCriticalThreatCallback != null) {
|
|
_onCriticalThreatCallback!();
|
|
}
|
|
}
|
|
}
|
|
}
|