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.
HMG_Patient_App_New/lib/services/security_service.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!();
}
}
}
}