ai_root_shield 0.5.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +52 -4
- data/README.md +33 -2
- data/bindings/python/README.md +304 -0
- data/bindings/python/ai_root_shield.py +438 -0
- data/bindings/python/setup.py +65 -0
- data/examples/device_logs/android_safetynet_device.json +148 -0
- data/examples/device_logs/ios_jailbroken_device.json +172 -0
- data/lib/ai_root_shield/ci_cd/security_test_module.rb +743 -0
- data/lib/ai_root_shield/dashboard/web_dashboard.rb +441 -0
- data/lib/ai_root_shield/enterprise/alert_system.rb +601 -0
- data/lib/ai_root_shield/enterprise/hybrid_detection_engine.rb +650 -0
- data/lib/ai_root_shield/enterprise/performance_optimizer.rb +613 -0
- data/lib/ai_root_shield/enterprise/policy_manager.rb +637 -0
- data/lib/ai_root_shield/integrations/siem_connector.rb +695 -0
- data/lib/ai_root_shield/platform/android_security_module.rb +263 -0
- data/lib/ai_root_shield/platform/hardware_security_analyzer.rb +452 -0
- data/lib/ai_root_shield/platform/ios_security_module.rb +513 -0
- data/lib/ai_root_shield/platform/unified_report_generator.rb +613 -0
- data/lib/ai_root_shield/version.rb +1 -1
- data/security_test_artifacts/security_report.json +124 -0
- data/security_test_artifacts/security_results.sarif +16 -0
- data/security_test_artifacts/security_tests.xml +3 -0
- metadata +20 -1
@@ -0,0 +1,438 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
AI Root Shield Python Bindings
|
4
|
+
Enterprise-grade mobile security analysis library
|
5
|
+
"""
|
6
|
+
|
7
|
+
import json
|
8
|
+
import subprocess
|
9
|
+
import tempfile
|
10
|
+
import os
|
11
|
+
from typing import Dict, List, Optional, Union
|
12
|
+
from dataclasses import dataclass
|
13
|
+
from enum import Enum
|
14
|
+
|
15
|
+
class SecurityLevel(Enum):
|
16
|
+
LOW = "low"
|
17
|
+
MEDIUM = "medium"
|
18
|
+
HIGH = "high"
|
19
|
+
CRITICAL = "critical"
|
20
|
+
|
21
|
+
class Platform(Enum):
|
22
|
+
ANDROID = "android"
|
23
|
+
IOS = "ios"
|
24
|
+
CROSS_PLATFORM = "cross_platform"
|
25
|
+
|
26
|
+
@dataclass
|
27
|
+
class AnalysisResult:
|
28
|
+
risk_score: int
|
29
|
+
factors: List[str]
|
30
|
+
timestamp: str
|
31
|
+
version: str
|
32
|
+
platform: Optional[str] = None
|
33
|
+
compliance: Optional[Dict] = None
|
34
|
+
recommendations: Optional[List[str]] = None
|
35
|
+
|
36
|
+
@dataclass
|
37
|
+
class PolicyConfig:
|
38
|
+
industry_type: str
|
39
|
+
compliance_frameworks: List[str]
|
40
|
+
risk_thresholds: Dict[str, int]
|
41
|
+
requirements: Dict[str, Dict]
|
42
|
+
|
43
|
+
class AIRootShield:
|
44
|
+
"""Main AI Root Shield Python interface"""
|
45
|
+
|
46
|
+
def __init__(self, config: Optional[Dict] = None):
|
47
|
+
self.config = config or {}
|
48
|
+
self.gem_available = self._check_gem_availability()
|
49
|
+
if not self.gem_available:
|
50
|
+
raise RuntimeError("AI Root Shield Ruby gem not found. Please install: gem install ai_root_shield")
|
51
|
+
|
52
|
+
def _check_gem_availability(self) -> bool:
|
53
|
+
"""Check if AI Root Shield gem is available"""
|
54
|
+
try:
|
55
|
+
result = subprocess.run(['gem', 'list', 'ai_root_shield'],
|
56
|
+
capture_output=True, text=True, timeout=10)
|
57
|
+
return 'ai_root_shield' in result.stdout
|
58
|
+
except (subprocess.TimeoutExpired, FileNotFoundError):
|
59
|
+
return False
|
60
|
+
|
61
|
+
def analyze_device(self, device_logs: Union[str, Dict],
|
62
|
+
platform: Optional[Platform] = None,
|
63
|
+
config: Optional[Dict] = None) -> AnalysisResult:
|
64
|
+
"""Analyze device security using AI Root Shield"""
|
65
|
+
|
66
|
+
# Prepare device logs
|
67
|
+
if isinstance(device_logs, dict):
|
68
|
+
logs_file = self._write_temp_json(device_logs)
|
69
|
+
else:
|
70
|
+
logs_file = device_logs
|
71
|
+
|
72
|
+
try:
|
73
|
+
# Build command
|
74
|
+
cmd = ['ai_root_shield']
|
75
|
+
|
76
|
+
if platform:
|
77
|
+
cmd.extend(['--platform', platform.value])
|
78
|
+
|
79
|
+
if config:
|
80
|
+
if config.get('verbose'):
|
81
|
+
cmd.append('--verbose')
|
82
|
+
if config.get('format'):
|
83
|
+
cmd.extend(['--format', config['format']])
|
84
|
+
if config.get('unified_report'):
|
85
|
+
cmd.append('--unified-report')
|
86
|
+
|
87
|
+
cmd.append(logs_file)
|
88
|
+
|
89
|
+
# Execute analysis
|
90
|
+
result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
|
91
|
+
|
92
|
+
if result.returncode != 0:
|
93
|
+
raise RuntimeError(f"Analysis failed: {result.stderr}")
|
94
|
+
|
95
|
+
# Parse result
|
96
|
+
analysis_data = json.loads(result.stdout)
|
97
|
+
return self._parse_analysis_result(analysis_data)
|
98
|
+
|
99
|
+
finally:
|
100
|
+
# Clean up temp file if created
|
101
|
+
if isinstance(device_logs, dict) and os.path.exists(logs_file):
|
102
|
+
os.unlink(logs_file)
|
103
|
+
|
104
|
+
def analyze_android_device(self, device_logs: Union[str, Dict],
|
105
|
+
safetynet_api_key: Optional[str] = None,
|
106
|
+
package_name: Optional[str] = None) -> AnalysisResult:
|
107
|
+
"""Analyze Android device with SafetyNet integration"""
|
108
|
+
config = {}
|
109
|
+
if safetynet_api_key:
|
110
|
+
config['safetynet_api_key'] = safetynet_api_key
|
111
|
+
if package_name:
|
112
|
+
config['package_name'] = package_name
|
113
|
+
|
114
|
+
return self.analyze_device(device_logs, Platform.ANDROID, config)
|
115
|
+
|
116
|
+
def analyze_ios_device(self, device_logs: Union[str, Dict]) -> AnalysisResult:
|
117
|
+
"""Analyze iOS device with jailbreak detection"""
|
118
|
+
return self.analyze_device(device_logs, Platform.IOS)
|
119
|
+
|
120
|
+
def run_ci_cd_analysis(self, device_logs: Union[str, Dict],
|
121
|
+
artifacts_path: str = './security_test_artifacts') -> Dict:
|
122
|
+
"""Run CI/CD security analysis"""
|
123
|
+
|
124
|
+
if isinstance(device_logs, dict):
|
125
|
+
logs_file = self._write_temp_json(device_logs)
|
126
|
+
else:
|
127
|
+
logs_file = device_logs
|
128
|
+
|
129
|
+
try:
|
130
|
+
cmd = ['ai_root_shield', '--ci-mode', '--artifacts-path', artifacts_path, logs_file]
|
131
|
+
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
|
132
|
+
|
133
|
+
if result.returncode != 0:
|
134
|
+
raise RuntimeError(f"CI/CD analysis failed: {result.stderr}")
|
135
|
+
|
136
|
+
return json.loads(result.stdout)
|
137
|
+
|
138
|
+
finally:
|
139
|
+
if isinstance(device_logs, dict) and os.path.exists(logs_file):
|
140
|
+
os.unlink(logs_file)
|
141
|
+
|
142
|
+
def generate_unified_report(self, android_results: Optional[Dict] = None,
|
143
|
+
ios_results: Optional[Dict] = None) -> Dict:
|
144
|
+
"""Generate unified cross-platform report"""
|
145
|
+
# This would require more complex integration with Ruby gem
|
146
|
+
# For now, use the CLI unified report feature
|
147
|
+
if android_results:
|
148
|
+
logs_file = self._write_temp_json(android_results)
|
149
|
+
try:
|
150
|
+
cmd = ['ai_root_shield', '--platform', 'android', '--unified-report', logs_file]
|
151
|
+
result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
|
152
|
+
|
153
|
+
if result.returncode == 0:
|
154
|
+
return json.loads(result.stdout)
|
155
|
+
finally:
|
156
|
+
os.unlink(logs_file)
|
157
|
+
|
158
|
+
return {}
|
159
|
+
|
160
|
+
def start_dashboard(self, port: int = 4567) -> bool:
|
161
|
+
"""Start web dashboard server"""
|
162
|
+
try:
|
163
|
+
cmd = ['ai_root_shield', '--start-dashboard', '--dashboard-port', str(port)]
|
164
|
+
subprocess.Popen(cmd)
|
165
|
+
return True
|
166
|
+
except Exception:
|
167
|
+
return False
|
168
|
+
|
169
|
+
def generate_ci_config(self, platform: str, output_path: Optional[str] = None) -> str:
|
170
|
+
"""Generate CI/CD configuration"""
|
171
|
+
try:
|
172
|
+
cmd = ['ai_root_shield', '--generate-ci-config', platform]
|
173
|
+
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
|
174
|
+
|
175
|
+
if result.returncode == 0:
|
176
|
+
return result.stdout
|
177
|
+
else:
|
178
|
+
raise RuntimeError(f"CI config generation failed: {result.stderr}")
|
179
|
+
except Exception as e:
|
180
|
+
raise RuntimeError(f"Failed to generate CI config: {str(e)}")
|
181
|
+
|
182
|
+
def _write_temp_json(self, data: Dict) -> str:
|
183
|
+
"""Write data to temporary JSON file"""
|
184
|
+
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
|
185
|
+
json.dump(data, f, indent=2)
|
186
|
+
return f.name
|
187
|
+
|
188
|
+
def _parse_analysis_result(self, data: Dict) -> AnalysisResult:
|
189
|
+
"""Parse analysis result from JSON"""
|
190
|
+
return AnalysisResult(
|
191
|
+
risk_score=data.get('risk_score', 0),
|
192
|
+
factors=data.get('factors', []),
|
193
|
+
timestamp=data.get('timestamp', ''),
|
194
|
+
version=data.get('version', ''),
|
195
|
+
platform=data.get('platform'),
|
196
|
+
compliance=data.get('compliance'),
|
197
|
+
recommendations=data.get('recommendations', [])
|
198
|
+
)
|
199
|
+
|
200
|
+
class EnterprisePolicy:
|
201
|
+
"""Enterprise policy management"""
|
202
|
+
|
203
|
+
def __init__(self, industry_type: str):
|
204
|
+
self.industry_type = industry_type
|
205
|
+
self.policy_config = self._load_policy_config()
|
206
|
+
|
207
|
+
def _load_policy_config(self) -> PolicyConfig:
|
208
|
+
"""Load policy configuration for industry"""
|
209
|
+
# This would integrate with the Ruby PolicyManager
|
210
|
+
# For now, return basic config
|
211
|
+
configs = {
|
212
|
+
'fintech': PolicyConfig(
|
213
|
+
industry_type='fintech',
|
214
|
+
compliance_frameworks=['pci_dss', 'sox', 'ffiec'],
|
215
|
+
risk_thresholds={'critical': 0, 'high': 10, 'medium': 30, 'low': 50},
|
216
|
+
requirements={}
|
217
|
+
),
|
218
|
+
'healthcare': PolicyConfig(
|
219
|
+
industry_type='healthcare',
|
220
|
+
compliance_frameworks=['hipaa', 'hitech', 'gdpr'],
|
221
|
+
risk_thresholds={'critical': 0, 'high': 15, 'medium': 35, 'low': 60},
|
222
|
+
requirements={}
|
223
|
+
),
|
224
|
+
'government': PolicyConfig(
|
225
|
+
industry_type='government',
|
226
|
+
compliance_frameworks=['fisma', 'nist_800_53', 'fedramp'],
|
227
|
+
risk_thresholds={'critical': 0, 'high': 5, 'medium': 20, 'low': 40},
|
228
|
+
requirements={}
|
229
|
+
),
|
230
|
+
'corporate': PolicyConfig(
|
231
|
+
industry_type='corporate',
|
232
|
+
compliance_frameworks=['iso27001', 'gdpr', 'ccpa'],
|
233
|
+
risk_thresholds={'critical': 5, 'high': 25, 'medium': 50, 'low': 75},
|
234
|
+
requirements={}
|
235
|
+
)
|
236
|
+
}
|
237
|
+
|
238
|
+
return configs.get(self.industry_type, configs['corporate'])
|
239
|
+
|
240
|
+
def evaluate_compliance(self, analysis_result: AnalysisResult) -> Dict:
|
241
|
+
"""Evaluate compliance against policy"""
|
242
|
+
violations = []
|
243
|
+
|
244
|
+
# Basic compliance evaluation
|
245
|
+
if analysis_result.risk_score > self.policy_config.risk_thresholds['critical']:
|
246
|
+
violations.append({
|
247
|
+
'severity': 'critical',
|
248
|
+
'message': f'Risk score {analysis_result.risk_score} exceeds critical threshold'
|
249
|
+
})
|
250
|
+
|
251
|
+
return {
|
252
|
+
'compliant': len(violations) == 0,
|
253
|
+
'violations': violations,
|
254
|
+
'policy_version': '1.0',
|
255
|
+
'industry_type': self.industry_type,
|
256
|
+
'compliance_score': max(0, 100 - len(violations) * 25)
|
257
|
+
}
|
258
|
+
|
259
|
+
class AlertManager:
|
260
|
+
"""Alert and notification management"""
|
261
|
+
|
262
|
+
def __init__(self, config: Optional[Dict] = None):
|
263
|
+
self.config = config or {}
|
264
|
+
self.channels = []
|
265
|
+
|
266
|
+
def add_webhook_channel(self, url: str, headers: Optional[Dict] = None):
|
267
|
+
"""Add webhook notification channel"""
|
268
|
+
self.channels.append({
|
269
|
+
'type': 'webhook',
|
270
|
+
'url': url,
|
271
|
+
'headers': headers or {}
|
272
|
+
})
|
273
|
+
|
274
|
+
def add_slack_channel(self, webhook_url: str):
|
275
|
+
"""Add Slack notification channel"""
|
276
|
+
self.channels.append({
|
277
|
+
'type': 'slack',
|
278
|
+
'webhook_url': webhook_url
|
279
|
+
})
|
280
|
+
|
281
|
+
def send_security_alert(self, analysis_result: AnalysisResult, severity: str = 'warning'):
|
282
|
+
"""Send security alert"""
|
283
|
+
alert_data = {
|
284
|
+
'type': 'security_incident',
|
285
|
+
'severity': severity,
|
286
|
+
'title': 'Security Threat Detected',
|
287
|
+
'message': f'Risk score: {analysis_result.risk_score}/100',
|
288
|
+
'data': {
|
289
|
+
'risk_score': analysis_result.risk_score,
|
290
|
+
'factors': analysis_result.factors,
|
291
|
+
'timestamp': analysis_result.timestamp
|
292
|
+
}
|
293
|
+
}
|
294
|
+
|
295
|
+
return self._send_alert(alert_data)
|
296
|
+
|
297
|
+
def send_compliance_alert(self, compliance_result: Dict, policy_type: str):
|
298
|
+
"""Send compliance alert"""
|
299
|
+
severity = 'info' if compliance_result['compliant'] else 'critical'
|
300
|
+
|
301
|
+
alert_data = {
|
302
|
+
'type': 'compliance_violation',
|
303
|
+
'severity': severity,
|
304
|
+
'title': 'Compliance Status Update',
|
305
|
+
'message': f"Policy: {policy_type}, Status: {'COMPLIANT' if compliance_result['compliant'] else 'NON-COMPLIANT'}",
|
306
|
+
'data': compliance_result
|
307
|
+
}
|
308
|
+
|
309
|
+
return self._send_alert(alert_data)
|
310
|
+
|
311
|
+
def _send_alert(self, alert_data: Dict) -> Dict:
|
312
|
+
"""Send alert through configured channels"""
|
313
|
+
results = {}
|
314
|
+
|
315
|
+
for channel in self.channels:
|
316
|
+
try:
|
317
|
+
if channel['type'] == 'webhook':
|
318
|
+
result = self._send_webhook(channel, alert_data)
|
319
|
+
elif channel['type'] == 'slack':
|
320
|
+
result = self._send_slack(channel, alert_data)
|
321
|
+
else:
|
322
|
+
result = {'success': False, 'error': 'Unknown channel type'}
|
323
|
+
|
324
|
+
results[f"{channel['type']}_{len(results)}"] = result
|
325
|
+
|
326
|
+
except Exception as e:
|
327
|
+
results[f"{channel['type']}_{len(results)}"] = {
|
328
|
+
'success': False,
|
329
|
+
'error': str(e)
|
330
|
+
}
|
331
|
+
|
332
|
+
return results
|
333
|
+
|
334
|
+
def _send_webhook(self, channel: Dict, alert_data: Dict) -> Dict:
|
335
|
+
"""Send webhook notification"""
|
336
|
+
import requests
|
337
|
+
|
338
|
+
try:
|
339
|
+
response = requests.post(
|
340
|
+
channel['url'],
|
341
|
+
json=alert_data,
|
342
|
+
headers=channel.get('headers', {}),
|
343
|
+
timeout=30
|
344
|
+
)
|
345
|
+
|
346
|
+
return {
|
347
|
+
'success': response.status_code < 400,
|
348
|
+
'status_code': response.status_code,
|
349
|
+
'response': response.text[:200] # Truncate response
|
350
|
+
}
|
351
|
+
except Exception as e:
|
352
|
+
return {'success': False, 'error': str(e)}
|
353
|
+
|
354
|
+
def _send_slack(self, channel: Dict, alert_data: Dict) -> Dict:
|
355
|
+
"""Send Slack notification"""
|
356
|
+
import requests
|
357
|
+
|
358
|
+
# Format for Slack
|
359
|
+
color = {
|
360
|
+
'info': 'good',
|
361
|
+
'warning': 'warning',
|
362
|
+
'critical': 'danger',
|
363
|
+
'emergency': 'danger'
|
364
|
+
}.get(alert_data['severity'], 'good')
|
365
|
+
|
366
|
+
payload = {
|
367
|
+
'text': alert_data['title'],
|
368
|
+
'attachments': [{
|
369
|
+
'color': color,
|
370
|
+
'fields': [
|
371
|
+
{'title': 'Severity', 'value': alert_data['severity'].upper(), 'short': True},
|
372
|
+
{'title': 'Type', 'value': alert_data['type'], 'short': True},
|
373
|
+
{'title': 'Message', 'value': alert_data['message'], 'short': False}
|
374
|
+
]
|
375
|
+
}]
|
376
|
+
}
|
377
|
+
|
378
|
+
try:
|
379
|
+
response = requests.post(channel['webhook_url'], json=payload, timeout=30)
|
380
|
+
return {
|
381
|
+
'success': response.status_code == 200,
|
382
|
+
'status_code': response.status_code
|
383
|
+
}
|
384
|
+
except Exception as e:
|
385
|
+
return {'success': False, 'error': str(e)}
|
386
|
+
|
387
|
+
# Example usage and testing functions
|
388
|
+
def example_usage():
|
389
|
+
"""Example usage of AI Root Shield Python bindings"""
|
390
|
+
|
391
|
+
# Initialize AI Root Shield
|
392
|
+
ars = AIRootShield()
|
393
|
+
|
394
|
+
# Example device logs
|
395
|
+
android_logs = {
|
396
|
+
"device_info": {
|
397
|
+
"platform": "Android",
|
398
|
+
"version": "11",
|
399
|
+
"model": "Pixel 5"
|
400
|
+
},
|
401
|
+
"security_checks": {
|
402
|
+
"root_detected": False,
|
403
|
+
"emulator_detected": False,
|
404
|
+
"debugging_enabled": False
|
405
|
+
},
|
406
|
+
"safetynet": {
|
407
|
+
"basicIntegrity": True,
|
408
|
+
"ctsProfileMatch": True
|
409
|
+
}
|
410
|
+
}
|
411
|
+
|
412
|
+
try:
|
413
|
+
# Analyze Android device
|
414
|
+
result = ars.analyze_android_device(android_logs)
|
415
|
+
print(f"Risk Score: {result.risk_score}/100")
|
416
|
+
print(f"Factors: {result.factors}")
|
417
|
+
|
418
|
+
# Enterprise policy evaluation
|
419
|
+
policy = EnterprisePolicy('fintech')
|
420
|
+
compliance = policy.evaluate_compliance(result)
|
421
|
+
print(f"Compliant: {compliance['compliant']}")
|
422
|
+
|
423
|
+
# Alert management
|
424
|
+
alert_manager = AlertManager()
|
425
|
+
alert_manager.add_webhook_channel('https://example.com/webhook')
|
426
|
+
|
427
|
+
if result.risk_score > 50:
|
428
|
+
alert_results = alert_manager.send_security_alert(result, 'warning')
|
429
|
+
print(f"Alert sent: {alert_results}")
|
430
|
+
|
431
|
+
return True
|
432
|
+
|
433
|
+
except Exception as e:
|
434
|
+
print(f"Error: {e}")
|
435
|
+
return False
|
436
|
+
|
437
|
+
if __name__ == "__main__":
|
438
|
+
example_usage()
|
@@ -0,0 +1,65 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
Setup script for AI Root Shield Python bindings
|
4
|
+
"""
|
5
|
+
|
6
|
+
from setuptools import setup, find_packages
|
7
|
+
import os
|
8
|
+
|
9
|
+
# Read README for long description
|
10
|
+
def read_readme():
|
11
|
+
readme_path = os.path.join(os.path.dirname(__file__), 'README.md')
|
12
|
+
if os.path.exists(readme_path):
|
13
|
+
with open(readme_path, 'r', encoding='utf-8') as f:
|
14
|
+
return f.read()
|
15
|
+
return "AI Root Shield Python bindings for enterprise mobile security analysis"
|
16
|
+
|
17
|
+
setup(
|
18
|
+
name="ai-root-shield",
|
19
|
+
version="1.0.0",
|
20
|
+
author="AI Root Shield Team",
|
21
|
+
author_email="support@airootshield.com",
|
22
|
+
description="Enterprise-grade mobile security analysis library - Python bindings",
|
23
|
+
long_description=read_readme(),
|
24
|
+
long_description_content_type="text/markdown",
|
25
|
+
url="https://github.com/ahmetxhero/ai-root-shield",
|
26
|
+
py_modules=["ai_root_shield"],
|
27
|
+
classifiers=[
|
28
|
+
"Development Status :: 5 - Production/Stable",
|
29
|
+
"Intended Audience :: Developers",
|
30
|
+
"Intended Audience :: Information Technology",
|
31
|
+
"License :: OSI Approved :: MIT License",
|
32
|
+
"Operating System :: OS Independent",
|
33
|
+
"Programming Language :: Python :: 3",
|
34
|
+
"Programming Language :: Python :: 3.7",
|
35
|
+
"Programming Language :: Python :: 3.8",
|
36
|
+
"Programming Language :: Python :: 3.9",
|
37
|
+
"Programming Language :: Python :: 3.10",
|
38
|
+
"Programming Language :: Python :: 3.11",
|
39
|
+
"Topic :: Security",
|
40
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
41
|
+
],
|
42
|
+
python_requires=">=3.7",
|
43
|
+
install_requires=[
|
44
|
+
"requests>=2.25.0",
|
45
|
+
],
|
46
|
+
extras_require={
|
47
|
+
"dev": [
|
48
|
+
"pytest>=6.0",
|
49
|
+
"pytest-cov>=2.0",
|
50
|
+
"black>=21.0",
|
51
|
+
"flake8>=3.8",
|
52
|
+
],
|
53
|
+
},
|
54
|
+
entry_points={
|
55
|
+
"console_scripts": [
|
56
|
+
"ai-root-shield=ai_root_shield:main",
|
57
|
+
],
|
58
|
+
},
|
59
|
+
keywords="security mobile android ios enterprise compliance fintech healthcare",
|
60
|
+
project_urls={
|
61
|
+
"Bug Reports": "https://github.com/ahmetxhero/ai-root-shield/issues",
|
62
|
+
"Source": "https://github.com/ahmetxhero/ai-root-shield",
|
63
|
+
"Documentation": "https://github.com/ahmetxhero/ai-root-shield/blob/main/README.md",
|
64
|
+
},
|
65
|
+
)
|
@@ -0,0 +1,148 @@
|
|
1
|
+
{
|
2
|
+
"platform": "android",
|
3
|
+
"timestamp": 1640995200,
|
4
|
+
"device_info": {
|
5
|
+
"model": "Pixel 6",
|
6
|
+
"manufacturer": "Google",
|
7
|
+
"os_version": "13",
|
8
|
+
"api_level": 33,
|
9
|
+
"build_fingerprint": "google/raven/raven:13/TQ3A.230805.001/10316531:user/release-keys"
|
10
|
+
},
|
11
|
+
"safetynet": {
|
12
|
+
"basicIntegrity": true,
|
13
|
+
"ctsProfileMatch": true,
|
14
|
+
"evaluationType": "BASIC",
|
15
|
+
"nonce": "R2Rra24fVm5xa2Mg",
|
16
|
+
"timestampMs": 1640995200000,
|
17
|
+
"advice": ["LOCK_SCREEN_SECURED"]
|
18
|
+
},
|
19
|
+
"play_integrity": {
|
20
|
+
"deviceIntegrity": {
|
21
|
+
"deviceRecognitionVerdict": ["MEETS_DEVICE_INTEGRITY", "MEETS_BASIC_INTEGRITY"]
|
22
|
+
},
|
23
|
+
"appIntegrity": {
|
24
|
+
"verdict": "PLAY_RECOGNIZED",
|
25
|
+
"appLicensingVerdict": "LICENSED"
|
26
|
+
},
|
27
|
+
"accountDetails": {
|
28
|
+
"verdict": "LICENSED"
|
29
|
+
},
|
30
|
+
"environmentDetails": {
|
31
|
+
"verdict": "MEETS_BASIC_INTEGRITY"
|
32
|
+
}
|
33
|
+
},
|
34
|
+
"hardware_security": {
|
35
|
+
"tee": {
|
36
|
+
"available": true,
|
37
|
+
"implementation": "trustzone",
|
38
|
+
"version": "1.1",
|
39
|
+
"secureStorage": true,
|
40
|
+
"keyAttestation": true,
|
41
|
+
"biometricSupport": true,
|
42
|
+
"strongboxAvailable": true,
|
43
|
+
"secureBootVerified": true,
|
44
|
+
"attestationKeys": ["rsa2048", "ec256"]
|
45
|
+
},
|
46
|
+
"secure_element": {
|
47
|
+
"available": true,
|
48
|
+
"type": "embedded_se",
|
49
|
+
"appletsInstalled": ["payment", "identity"],
|
50
|
+
"nfcSecureElement": true,
|
51
|
+
"embeddedSecureElement": true,
|
52
|
+
"tamperResistance": true,
|
53
|
+
"certificationLevel": "cc_eal5_plus"
|
54
|
+
},
|
55
|
+
"biometrics": {
|
56
|
+
"fingerprintAvailable": true,
|
57
|
+
"faceAvailable": false,
|
58
|
+
"fingerprintEnrolled": true,
|
59
|
+
"hardwareLevel": "strong",
|
60
|
+
"template_security": {
|
61
|
+
"hardwareProtected": true,
|
62
|
+
"encryptedStorage": true,
|
63
|
+
"templateIsolation": true,
|
64
|
+
"secureMatching": true
|
65
|
+
},
|
66
|
+
"liveness_detection": {
|
67
|
+
"activeLiveness": true,
|
68
|
+
"passiveLiveness": true,
|
69
|
+
"depthSensing": false
|
70
|
+
},
|
71
|
+
"consistency": {
|
72
|
+
"enrollmentChangesDetected": false,
|
73
|
+
"templateModifications": false
|
74
|
+
}
|
75
|
+
},
|
76
|
+
"crypto": {
|
77
|
+
"hardwareRng": true,
|
78
|
+
"aesHardwareAcceleration": true,
|
79
|
+
"eccSupport": true,
|
80
|
+
"rsaSupport": true,
|
81
|
+
"keyDerivationHardware": true,
|
82
|
+
"secureKeyStorage": true,
|
83
|
+
"cryptoCoprocessor": true,
|
84
|
+
"supportedAlgorithms": ["AES-256", "RSA-2048", "ECDSA-P256", "SHA-256"]
|
85
|
+
},
|
86
|
+
"attestation": {
|
87
|
+
"keyAttestationSupported": true,
|
88
|
+
"attestationSecurityLevel": "trusted_environment",
|
89
|
+
"deviceIdAttestation": true,
|
90
|
+
"verifiedBootKey": "308201a2300d06092a864886f70d01010105000382018f003082018a0282018100...",
|
91
|
+
"rootOfTrust": {
|
92
|
+
"verifiedBootKey": "308201a2300d06092a864886f70d01010105000382018f003082018a0282018100...",
|
93
|
+
"deviceLocked": true,
|
94
|
+
"verifiedBootState": "verified",
|
95
|
+
"verifiedBootHash": "4f4adce36cf2e9c51349d1e77b067b2b8b5c5b5c5b5c5b5c5b5c5b5c5b5c5b5c"
|
96
|
+
}
|
97
|
+
}
|
98
|
+
},
|
99
|
+
"system_integrity": {
|
100
|
+
"selinuxEnforcing": true,
|
101
|
+
"verifiedBootState": "green",
|
102
|
+
"bootloaderLocked": true,
|
103
|
+
"systemPartitionVerified": true,
|
104
|
+
"vendorPartitionVerified": true,
|
105
|
+
"buildTags": "release-keys",
|
106
|
+
"adbEnabled": false,
|
107
|
+
"developerOptionsEnabled": false,
|
108
|
+
"dmVerityEnabled": true
|
109
|
+
},
|
110
|
+
"file_system": {
|
111
|
+
"files": [
|
112
|
+
{
|
113
|
+
"path": "/system/bin/sh",
|
114
|
+
"permissions": "755",
|
115
|
+
"owner": "root",
|
116
|
+
"exists": true
|
117
|
+
},
|
118
|
+
{
|
119
|
+
"path": "/system/xbin/su",
|
120
|
+
"exists": false
|
121
|
+
},
|
122
|
+
{
|
123
|
+
"path": "/system/bin/su",
|
124
|
+
"exists": false
|
125
|
+
}
|
126
|
+
]
|
127
|
+
},
|
128
|
+
"running_processes": [
|
129
|
+
{
|
130
|
+
"name": "system_server",
|
131
|
+
"pid": 1234,
|
132
|
+
"uid": 1000
|
133
|
+
},
|
134
|
+
{
|
135
|
+
"name": "zygote64",
|
136
|
+
"pid": 567,
|
137
|
+
"uid": 0
|
138
|
+
}
|
139
|
+
],
|
140
|
+
"network": {
|
141
|
+
"proxy_enabled": false,
|
142
|
+
"vpn_active": false,
|
143
|
+
"custom_certificates": [],
|
144
|
+
"tls_version": "1.3"
|
145
|
+
},
|
146
|
+
"risk_score": 15,
|
147
|
+
"factors": []
|
148
|
+
}
|