Skip to content

Understanding Scan Results

The Alphyn SDK provides detailed security scan results that help you make informed decisions about app security. Understanding these results is crucial for implementing appropriate security measures.

Here’s what the actual SDK output looks like:

// Device Information
Device ID: 817D56BE-0BC4-4CE4-8516-8F582EEBE0FC
App Hash: 64f3f5b47a856403dc48bfbaac0fcdb89f414f63dafb9c18e8b6d87f2a43caec
// Scan Result
Scan Result: SIMULATOR_RUNTIME
// Rejection Reasons (List<String>)
[
"DETECTION: COMMON_SUSPICIOUS_PATH Common suspicious file path accessible",
"DETECTION: SIMULATOR_ENVIRONMENT Simulator environment detected",
"DETECTION: SIMULATOR_RUNTIME Simulator runtime detected",
"DETECTION: DEBUGGER_SYSTEM_CHECK Debugger detected (system check)",
"DETECTION: DEBUGGER_PROCESS_CHECK Debugger detected (process check)",
"DETECTION: DEBUGGER_EXCEPTION_CHECK Debugger detected (exception check)",
"DETECTION: VPN_IN_USE VPN in use",
"DETECTION: FRIDA_DETECTED Frida traces detected"
]
// Risk Factors (List<String>)
[
"COMMON_SUSPICIOUS_PATH",
"SIMULATOR_ENVIRONMENT",
"SIMULATOR_RUNTIME",
"DEBUGGER_SYSTEM_CHECK",
"DEBUGGER_PROCESS_CHECK",
"DEBUGGER_EXCEPTION_CHECK",
"VPN_IN_USE",
"FRIDA_DETECTED",
"FRIDA_SERVER_RUNNING"
]
// All Scan Results (List<String>)
[
"ScanResult(date: 2025-11-20 11:21:29 +0000, detections: [\"Detection: COMMON_SUSPICIOUS_PATH Severity: HIGH\", \"Detection: SIMULATOR_RUNTIME Severity: CRITICAL\"])",
"ScanResult(date: 2025-11-20 11:21:30 +0000, detections: [\"Detection: FRIDA_DETECTED, FRIDA_SERVER_RUNNING Severity: CRITICAL\"])"
]
// Last Scan Date
2025-11-20 11:21:28.000Z
// Device Initialized Status
"true"

The SDK returns various types of security states based on the scan analysis:

ResultDescriptionSeverityRecommended Action
TRUSTEDApp passed all security checks✅ LowContinue normal operation
FLAGGEDPotential security concerns detected⚠️ MediumMonitor and investigate
UNTRUSTEDApp failed critical security checks🚨 HighRestrict functionality or terminate
UNKNOWNScan result unclear or invalid❓ UnknownRetry scan or investigate
INITIALIZATION_ERRORSDK failed to initialize properly⚠️ HighFix initialization issues
import 'package:alphyn_sdk/alphyn_sdk.dart';
Future<void> interpretScanResults() async {
try {
// Get the current scan result
final result = await AlphynSdk.getScanResult();
// Check if there are any rejection reasons
// getRejectReasons() returns a newline-separated string; split it into a list
final rejectReasonsRaw = await AlphynSdk.getRejectReasons();
final rejectReasons = rejectReasonsRaw.split('\n').where((line) => line.trim().isNotEmpty).toList();
// Example outputs:
// result: 'SIMULATOR_RUNTIME' or 'FRIDA_DETECTED'
// rejectReasons: [
// 'DETECTION: SIMULATOR_RUNTIME Simulator runtime detected',
// 'DETECTION: DEBUGGER_SYSTEM_CHECK Debugger detected (system check)',
// 'DETECTION: FRIDA_DETECTED Frida traces detected'
// ]
print('Raw Result: $result');
print('Rejection Reasons Count: ${rejectReasons.length}');
// Determine security status based on results
if (rejectReasons.isEmpty) {
print('✅ Status: TRUSTED');
print('Application verified as secure - no threats detected');
proceedWithNormalOperation();
} else if (rejectReasons.length < 3) {
print('⚠️ Status: FLAGGED');
print('Security concerns detected: ${rejectReasons.length}');
for (var reason in rejectReasons) {
print(' - $reason');
}
enableEnhancedMonitoring(rejectReasons);
} else if (rejectReasons.length >= 3) {
print('🚨 Status: UNTRUSTED');
print('Critical threats detected: ${rejectReasons.length} issues');
for (var reason in rejectReasons) {
print(' - $reason');
}
restrictFunctionality(rejectReasons);
} else {
print('❓ Status: UNKNOWN');
print('Unable to determine security status');
retryScan();
}
} catch (e) {
print('⚠️ Status: INITIALIZATION_ERROR');
print('SDK error: $e');
handleInitializationError(e);
}
}
Section titled “Strategy 1: Graceful Degradation (Recommended)”

Gradually restrict functionality based on threat severity:

class SecurityManager {
static Future<void> handleSecurityStatus() async {
// getRejectReasons() returns a newline-separated string; split it into a list
final rejectReasonsRaw = await AlphynSdk.getRejectReasons();
final rejectReasons = rejectReasonsRaw.split('\n').where((line) => line.trim().isNotEmpty).toList();
final riskFactors = await AlphynSdk.getAllRiskFactors();
if (rejectReasons.isEmpty) {
// TRUSTED - Full functionality
print('✅ Full access granted');
enableAllFeatures();
} else if (rejectReasons.length < 3) {
// FLAGGED - Limited functionality
print('⚠️ Operating in restricted mode');
disableSensitiveFeatures();
logSecurityEvent(rejectReasons);
showSecurityWarning();
} else {
// UNTRUSTED - Minimal or no functionality
print('🚨 Critical security violation');
disableAllSensitiveFeatures();
logCriticalSecurityEvent(rejectReasons);
showCriticalSecurityAlert();
}
}
static void enableAllFeatures() {
// Enable payments, sensitive data access, etc.
}
static void disableSensitiveFeatures() {
// Disable payments, limit data access
}
static void disableAllSensitiveFeatures() {
// Block all sensitive operations
}
static void showSecurityWarning() {
// Show user-friendly warning dialog
}
static void showCriticalSecurityAlert() {
// Show critical security alert with explanation
}
static void logSecurityEvent(List<String> reasons) {
// Log to analytics/monitoring service
}
static void logCriticalSecurityEvent(List<String> reasons) {
// Log critical event with full details
}
}

Make decisions based on specific risk factors:

class RiskBasedSecurityHandler {
static Future<void> evaluateSecurity() async {
// getRejectReasons() returns a newline-separated string; split it into a list
final rejectReasonsRaw = await AlphynSdk.getRejectReasons();
final rejectReasons = rejectReasonsRaw.split('\n').where((line) => line.trim().isNotEmpty).toList();
final riskFactors = await AlphynSdk.getAllRiskFactors();
// Check for critical threats
final hasCriticalThreats = _checkCriticalThreats(rejectReasons);
final hasDebuggerAttached = _checkDebugger(rejectReasons);
final isRooted = _checkRootAccess(rejectReasons);
if (hasCriticalThreats) {
print('🚨 Critical threat detected - terminating');
terminateApp();
} else if (hasDebuggerAttached) {
print('⚠️ Debugger detected - limiting functionality');
disableDebugSensitiveFeatures();
} else if (isRooted) {
print('⚠️ Root/Jailbreak detected');
handleRootedDevice();
} else {
print('✅ No significant threats');
proceedNormally();
}
}
static bool _checkCriticalThreats(List<String> reasons) {
// Check for critical detection types from actual SDK output
final criticalDetections = [
'FRIDA_DETECTED',
'FRIDA_SERVER_RUNNING',
'SIMULATOR_RUNTIME',
'HOOK_DETECTED',
'TAMPERED',
'MODIFIED'
];
return reasons.any((reason) =>
criticalDetections.any((detection) =>
reason.toUpperCase().contains(detection)
)
);
}
static bool _checkDebugger(List<String> reasons) {
// Check for debugger-related detections
final debuggerDetections = [
'DEBUGGER_SYSTEM_CHECK',
'DEBUGGER_PROCESS_CHECK',
'DEBUGGER_EXCEPTION_CHECK'
];
return reasons.any((reason) =>
debuggerDetections.any((detection) =>
reason.toUpperCase().contains(detection)
)
);
}
static bool _checkRootAccess(List<String> reasons) {
// Check for root/jailbreak detections
final rootDetections = [
'ROOT_DETECTED',
'JAILBREAK_DETECTED',
'SUPERUSER',
'SU_BINARY'
];
return reasons.any((reason) =>
rootDetections.any((detection) =>
reason.toUpperCase().contains(detection)
)
);
}
static bool _checkSimulatorOrEmulator(List<String> reasons) {
// Check for simulator/emulator detections
final simulatorDetections = [
'SIMULATOR_ENVIRONMENT',
'SIMULATOR_RUNTIME',
'EMULATOR_DETECTED'
];
return reasons.any((reason) =>
simulatorDetections.any((detection) =>
reason.toUpperCase().contains(detection)
)
);
}
static void terminateApp() {
// Log event and exit app
// SystemNavigator.pop() or exit(0)
}
static void disableDebugSensitiveFeatures() {
// Disable features vulnerable to debugging
}
static void handleRootedDevice() {
// Show warning or restrict features
}
static void proceedNormally() {
// Continue with full functionality
}
}

Implement periodic security checks:

class ContinuousSecurityMonitor {
Timer? _monitoringTimer;
void startMonitoring({Duration interval = const Duration(minutes: 5)}) {
_monitoringTimer?.cancel();
_monitoringTimer = Timer.periodic(interval, (timer) async {
await performSecurityCheck();
});
// Initial check
performSecurityCheck();
}
void stopMonitoring() {
_monitoringTimer?.cancel();
_monitoringTimer = null;
}
Future<void> performSecurityCheck() async {
try {
// getRejectReasons() returns a newline-separated string; split it into a list
final rejectReasonsRaw = await AlphynSdk.getRejectReasons();
final rejectReasons = rejectReasonsRaw.split('\n').where((line) => line.trim().isNotEmpty).toList();
final lastScanDate = await AlphynSdk.getLastScanDate();
print('🔍 Security check at: ${DateTime.now()}');
print('Last scan: $lastScanDate');
print('Threats: ${rejectReasons.length}');
if (rejectReasons.isNotEmpty) {
handleSecurityThreats(rejectReasons);
}
// Check if scan is stale (older than expected interval)
if (lastScanDate != null) {
final timeSinceLastScan = DateTime.now().difference(lastScanDate);
if (timeSinceLastScan > const Duration(minutes: 10)) {
print('⚠️ Warning: Scan data is stale');
}
}
} catch (e) {
print('❌ Security check failed: $e');
}
}
void handleSecurityThreats(List<String> threats) {
// Implement threat response logic
for (var threat in threats) {
print('⚠️ Threat detected: $threat');
}
}
}
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:alphyn_sdk/alphyn_sdk.dart';
class SecureApp extends StatefulWidget {
@override
_SecureAppState createState() => _SecureAppState();
}
class _SecureAppState extends State<SecureApp> {
SecurityLevel _securityLevel = SecurityLevel.unknown;
List<String> _threats = [];
bool _isMonitoring = false;
@override
void initState() {
super.initState();
_initializeSecurity();
}
Future<void> _initializeSecurity() async {
try {
// Check if SDK is initialized
final isInitialized = await AlphynSdk.isInitialized();
if (isInitialized != true) {
setState(() {
_securityLevel = SecurityLevel.initializationError;
});
return;
}
// Perform initial security check
await _performSecurityCheck();
// Start continuous monitoring
_startContinuousMonitoring();
} catch (e) {
print('Security initialization error: $e');
setState(() {
_securityLevel = SecurityLevel.initializationError;
});
}
}
Future<void> _performSecurityCheck() async {
try {
// getRejectReasons() returns a newline-separated string; split it into a list
final rejectReasonsRaw = await AlphynSdk.getRejectReasons();
final rejectReasons = rejectReasonsRaw.split('\n').where((line) => line.trim().isNotEmpty).toList();
final result = await AlphynSdk.getScanResult();
setState(() {
_threats = rejectReasons;
_securityLevel = _determineSecurityLevel(rejectReasons, result);
});
_applySecurityPolicy(_securityLevel);
} catch (e) {
print('Security check error: $e');
}
}
SecurityLevel _determineSecurityLevel(List<String> threats, String? result) {
// Device is trusted if no threats detected
if (threats.isEmpty) {
return SecurityLevel.trusted;
} else if (threats.length < 3) {
return SecurityLevel.flagged;
} else {
return SecurityLevel.untrusted;
}
}
void _applySecurityPolicy(SecurityLevel level) {
switch (level) {
case SecurityLevel.trusted:
print('✅ Security Policy: Full Access');
break;
case SecurityLevel.flagged:
print('⚠️ Security Policy: Restricted Access');
_showSecurityWarning();
break;
case SecurityLevel.untrusted:
print('🚨 Security Policy: Critical Restriction');
_showCriticalAlert();
break;
case SecurityLevel.unknown:
case SecurityLevel.initializationError:
print('❓ Security Policy: Unable to determine');
break;
}
}
void _startContinuousMonitoring() {
if (_isMonitoring) return;
_isMonitoring = true;
Timer.periodic(const Duration(minutes: 5), (timer) {
if (!mounted) {
timer.cancel();
return;
}
_performSecurityCheck();
});
}
void _showSecurityWarning() {
if (!mounted) return;
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Row(
children: [
Icon(Icons.warning_amber, color: Colors.orange),
SizedBox(width: 8),
Text('Security Notice'),
],
),
content: Text(
'Security concerns detected:\n\n${_threats.join('\n')}',
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Acknowledge'),
),
],
),
);
}
void _showCriticalAlert() {
if (!mounted) return;
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => AlertDialog(
title: const Row(
children: [
Icon(Icons.error, color: Colors.red),
SizedBox(width: 8),
Text('Critical Security Alert'),
],
),
content: Text(
'Critical security violations detected:\n\n${_threats.join('\n')}\n\n'
'Sensitive features have been disabled for your protection.',
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('I Understand'),
),
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Secure Application'),
backgroundColor: _getSecurityColor(),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
_getSecurityIcon(),
size: 64,
color: _getSecurityColor(),
),
const SizedBox(height: 16),
Text(
_securityLevel.displayName,
style: Theme.of(context).textTheme.headlineMedium,
),
if (_threats.isNotEmpty) ...[
const SizedBox(height: 24),
Text(
'Threats detected: ${_threats.length}',
style: Theme.of(context).textTheme.bodyLarge,
),
],
],
),
),
);
}
Color _getSecurityColor() {
switch (_securityLevel) {
case SecurityLevel.trusted:
return Colors.green;
case SecurityLevel.flagged:
return Colors.orange;
case SecurityLevel.untrusted:
return Colors.red;
default:
return Colors.grey;
}
}
IconData _getSecurityIcon() {
switch (_securityLevel) {
case SecurityLevel.trusted:
return Icons.verified_user;
case SecurityLevel.flagged:
return Icons.warning;
case SecurityLevel.untrusted:
return Icons.dangerous;
default:
return Icons.help;
}
}
}
enum SecurityLevel {
trusted,
flagged,
untrusted,
unknown,
initializationError;
String get displayName {
switch (this) {
case SecurityLevel.trusted:
return 'Trusted';
case SecurityLevel.flagged:
return 'Flagged';
case SecurityLevel.untrusted:
return 'Untrusted';
case SecurityLevel.unknown:
return 'Unknown';
case SecurityLevel.initializationError:
return 'Initialization Error';
}
}
}
  1. Never Ignore Security Warnings: Always handle FLAGGED and UNTRUSTED statuses appropriately
  2. Implement Graceful Degradation: Instead of completely blocking users, gradually restrict sensitive features
  3. Log Security Events: Always log security violations for analysis and compliance
  4. User Communication: Inform users about security issues in a clear, non-technical manner
  5. Regular Checks: Implement periodic security scans, especially after app resume
  6. Test Thoroughly: Test your security response logic in various scenarios
  7. Monitor Trends: Track security events over time to identify patterns

The SDK can detect various security threats. Below are the actual detection types returned by the SDK:

Development & Testing Environment Detections

Section titled “Development & Testing Environment Detections”
  • SIMULATOR_ENVIRONMENT: App running in iOS simulator
  • SIMULATOR_RUNTIME: Simulator runtime environment detected
  • EMULATOR_DETECTED: Android emulator detected
  • DEBUGGER_SYSTEM_CHECK: Debugger detected via system checks
  • DEBUGGER_PROCESS_CHECK: Debugger detected via process inspection
  • DEBUGGER_EXCEPTION_CHECK: Debugger detected via exception handling
  • FRIDA_DETECTED: Frida dynamic instrumentation framework detected
  • FRIDA_SERVER_RUNNING: Active Frida server found
  • COMMON_SUSPICIOUS_PATH: Suspicious file paths accessible
  • VPN_IN_USE: VPN connection detected
  • ROOT_DETECTED: Device has root/jailbreak access
  • HOOK_DETECTED: Runtime hooking framework detected
  • TAMPERED: App binary or resources modified
  • REPACKAGED: App has been decompiled and repackaged

All detections follow this format:

DETECTION: <TYPE> <Description>

Example:

DETECTION: FRIDA_DETECTED Frida traces detected
DETECTION: SIMULATOR_RUNTIME Simulator runtime detected
DETECTION: DEBUGGER_SYSTEM_CHECK Debugger detected (system check)

Parsing Detection Types:

class DetectionInfo {
final String type;
final String description;
DetectionInfo(this.type, this.description);
@override
String toString() => 'DetectionInfo(type: $type, description: $description)';
}
DetectionInfo? parseDetection(String detection) {
if (detection.startsWith('DETECTION:')) {
// Remove 'DETECTION: ' prefix
final withoutPrefix = detection.substring(11).trim();
// Split into type and description
final firstSpaceIndex = withoutPrefix.indexOf(' ');
if (firstSpaceIndex > 0) {
final type = withoutPrefix.substring(0, firstSpaceIndex);
final description = withoutPrefix.substring(firstSpaceIndex + 1);
return DetectionInfo(type, description);
} else {
// No description, just type
return DetectionInfo(withoutPrefix, '');
}
}
return null;
}
// Example usage with real data
// getRejectReasons() returns a newline-separated string; split it into a list
final rejectReasonsRaw = await AlphynSdk.getRejectReasons();
final rejectReasons = rejectReasonsRaw.split('\n').where((line) => line.trim().isNotEmpty).toList();
for (var reason in rejectReasons) {
final detection = parseDetection(reason);
if (detection != null) {
print('Type: ${detection.type}');
print('Description: ${detection.description}');
print('---');
}
}
// Example output:
// Type: FRIDA_DETECTED
// Description: Frida traces detected
// ---
// Type: SIMULATOR_RUNTIME
// Description: Simulator runtime detected
// ---
// Type: DEBUGGER_SYSTEM_CHECK
// Description: Debugger detected (system check)
// ---
// Check for specific detection types
bool hasFridaDetection(List<String> reasons) {
return reasons.any((reason) =>
parseDetection(reason)?.type == 'FRIDA_DETECTED' ||
parseDetection(reason)?.type == 'FRIDA_SERVER_RUNNING'
);
}
bool hasDebuggerDetection(List<String> reasons) {
return reasons.any((reason) {
final type = parseDetection(reason)?.type ?? '';
return type.startsWith('DEBUGGER_');
});
}
bool hasSimulatorDetection(List<String> reasons) {
return reasons.any((reason) {
final type = parseDetection(reason)?.type ?? '';
return type.startsWith('SIMULATOR_') || type == 'EMULATOR_DETECTED';
});
}