ai_root_shield 0.4.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.
@@ -0,0 +1,441 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sinatra/base'
4
+ require 'json'
5
+ require 'erb'
6
+
7
+ module AiRootShield
8
+ module Dashboard
9
+ # Optional GUI dashboard for log analysis and visualization
10
+ class WebDashboard < Sinatra::Base
11
+ set :port, 4567
12
+ set :bind, '0.0.0.0'
13
+ set :public_folder, File.join(__dir__, 'public')
14
+ set :views, File.join(__dir__, 'views')
15
+
16
+ # Dashboard routes
17
+ get '/' do
18
+ @title = 'AI Root Shield Dashboard'
19
+ erb :index
20
+ end
21
+
22
+ get '/api/status' do
23
+ content_type :json
24
+ {
25
+ status: 'running',
26
+ version: AiRootShield::VERSION,
27
+ timestamp: Time.now.utc.iso8601
28
+ }.to_json
29
+ end
30
+
31
+ post '/api/analyze' do
32
+ content_type :json
33
+
34
+ begin
35
+ # Parse uploaded device logs
36
+ device_logs = JSON.parse(request.body.read)
37
+
38
+ # Perform security analysis
39
+ results = perform_security_analysis(device_logs)
40
+
41
+ # Generate visualization data
42
+ visualization_data = generate_visualization_data(results)
43
+
44
+ {
45
+ success: true,
46
+ results: results,
47
+ visualization: visualization_data
48
+ }.to_json
49
+
50
+ rescue JSON::ParserError => e
51
+ status 400
52
+ { success: false, error: "Invalid JSON: #{e.message}" }.to_json
53
+ rescue StandardError => e
54
+ status 500
55
+ { success: false, error: "Analysis failed: #{e.message}" }.to_json
56
+ end
57
+ end
58
+
59
+ get '/api/reports' do
60
+ content_type :json
61
+
62
+ # Get list of available reports
63
+ reports = get_available_reports
64
+ { reports: reports }.to_json
65
+ end
66
+
67
+ get '/api/reports/:id' do
68
+ content_type :json
69
+
70
+ report_id = params[:id]
71
+ report = get_report_by_id(report_id)
72
+
73
+ if report
74
+ report.to_json
75
+ else
76
+ status 404
77
+ { success: false, error: 'Report not found' }.to_json
78
+ end
79
+ end
80
+
81
+ get '/dashboard' do
82
+ @title = 'Security Dashboard'
83
+ @recent_scans = get_recent_scans
84
+ erb :dashboard
85
+ end
86
+
87
+ get '/visualization' do
88
+ @title = 'Risk Visualization'
89
+ erb :visualization
90
+ end
91
+
92
+ get '/reports' do
93
+ @title = 'Security Reports'
94
+ @reports = get_available_reports
95
+ erb :reports
96
+ end
97
+
98
+ get '/settings' do
99
+ @title = 'Dashboard Settings'
100
+ erb :settings
101
+ end
102
+
103
+ private
104
+
105
+ def perform_security_analysis(device_logs)
106
+ platform = device_logs['platform']&.downcase
107
+
108
+ case platform
109
+ when 'android'
110
+ android_module = AiRootShield::Platform::AndroidSecurityModule.new
111
+ android_module.analyze_device_security(device_logs)
112
+ when 'ios'
113
+ ios_module = AiRootShield::Platform::IosSecurityModule.new
114
+ ios_module.analyze_device_security(device_logs)
115
+ else
116
+ # Generic analysis
117
+ {
118
+ risk_score: 0,
119
+ risk_factors: [],
120
+ platform: 'unknown',
121
+ analysis_type: 'generic'
122
+ }
123
+ end
124
+ end
125
+
126
+ def generate_visualization_data(results)
127
+ {
128
+ risk_score_chart: generate_risk_score_chart(results),
129
+ risk_factors_chart: generate_risk_factors_chart(results),
130
+ timeline_data: generate_timeline_data(results),
131
+ heatmap_data: generate_heatmap_data(results),
132
+ compliance_radar: generate_compliance_radar(results)
133
+ }
134
+ end
135
+
136
+ def generate_risk_score_chart(results)
137
+ risk_score = results[:risk_score] || 0
138
+
139
+ {
140
+ type: 'gauge',
141
+ data: {
142
+ value: risk_score,
143
+ max: 100,
144
+ ranges: [
145
+ { from: 0, to: 20, color: '#28a745', label: 'LOW' },
146
+ { from: 21, to: 40, color: '#ffc107', label: 'MEDIUM' },
147
+ { from: 41, to: 70, color: '#fd7e14', label: 'HIGH' },
148
+ { from: 71, to: 100, color: '#dc3545', label: 'CRITICAL' }
149
+ ]
150
+ },
151
+ options: {
152
+ title: 'Overall Risk Score',
153
+ subtitle: determine_risk_level(risk_score)
154
+ }
155
+ }
156
+ end
157
+
158
+ def generate_risk_factors_chart(results)
159
+ risk_factors = results[:risk_factors] || []
160
+
161
+ # Categorize risk factors
162
+ categories = {
163
+ 'Root/Jailbreak' => risk_factors.select { |f| f.match?(/ROOT|JAILBREAK/) }.size,
164
+ 'Emulator' => risk_factors.select { |f| f.match?(/EMULATOR/) }.size,
165
+ 'Hooking' => risk_factors.select { |f| f.match?(/FRIDA|XPOSED|SUBSTRATE/) }.size,
166
+ 'Integrity' => risk_factors.select { |f| f.match?(/INTEGRITY|SIGNING/) }.size,
167
+ 'Network' => risk_factors.select { |f| f.match?(/NETWORK|TLS|PROXY/) }.size,
168
+ 'Hardware' => risk_factors.select { |f| f.match?(/HARDWARE|TEE|BIOMETRIC/) }.size
169
+ }
170
+
171
+ {
172
+ type: 'bar',
173
+ data: {
174
+ labels: categories.keys,
175
+ datasets: [{
176
+ label: 'Risk Factors Count',
177
+ data: categories.values,
178
+ backgroundColor: [
179
+ '#dc3545', '#fd7e14', '#ffc107',
180
+ '#28a745', '#17a2b8', '#6f42c1'
181
+ ]
182
+ }]
183
+ },
184
+ options: {
185
+ title: 'Risk Factors by Category',
186
+ responsive: true
187
+ }
188
+ }
189
+ end
190
+
191
+ def generate_timeline_data(results)
192
+ # Generate timeline data for risk evolution
193
+ {
194
+ type: 'line',
195
+ data: {
196
+ labels: generate_time_labels,
197
+ datasets: [{
198
+ label: 'Risk Score Over Time',
199
+ data: generate_risk_timeline(results),
200
+ borderColor: '#dc3545',
201
+ backgroundColor: 'rgba(220, 53, 69, 0.1)',
202
+ tension: 0.4
203
+ }]
204
+ },
205
+ options: {
206
+ title: 'Risk Score Timeline',
207
+ scales: {
208
+ y: {
209
+ beginAtZero: true,
210
+ max: 100
211
+ }
212
+ }
213
+ }
214
+ }
215
+ end
216
+
217
+ def generate_heatmap_data(results)
218
+ # Generate security heatmap data
219
+ security_areas = [
220
+ 'Authentication', 'Authorization', 'Data Protection',
221
+ 'Network Security', 'Code Integrity', 'Runtime Protection',
222
+ 'Hardware Security', 'Compliance'
223
+ ]
224
+
225
+ heatmap_values = security_areas.map do |area|
226
+ calculate_area_risk_score(area, results)
227
+ end
228
+
229
+ {
230
+ type: 'heatmap',
231
+ data: {
232
+ labels: security_areas,
233
+ values: heatmap_values
234
+ },
235
+ options: {
236
+ title: 'Security Areas Heatmap',
237
+ colorScale: {
238
+ low: '#28a745',
239
+ medium: '#ffc107',
240
+ high: '#dc3545'
241
+ }
242
+ }
243
+ }
244
+ end
245
+
246
+ def generate_compliance_radar(results)
247
+ compliance_frameworks = [
248
+ 'OWASP MASVS', 'NIST Cybersecurity', 'ISO 27001',
249
+ 'PCI DSS', 'GDPR', 'SOX', 'HIPAA'
250
+ ]
251
+
252
+ compliance_scores = compliance_frameworks.map do |framework|
253
+ calculate_compliance_score(framework, results)
254
+ end
255
+
256
+ {
257
+ type: 'radar',
258
+ data: {
259
+ labels: compliance_frameworks,
260
+ datasets: [{
261
+ label: 'Compliance Score',
262
+ data: compliance_scores,
263
+ backgroundColor: 'rgba(40, 167, 69, 0.2)',
264
+ borderColor: '#28a745',
265
+ pointBackgroundColor: '#28a745'
266
+ }]
267
+ },
268
+ options: {
269
+ title: 'Compliance Framework Assessment',
270
+ scale: {
271
+ ticks: {
272
+ beginAtZero: true,
273
+ max: 100
274
+ }
275
+ }
276
+ }
277
+ }
278
+ end
279
+
280
+ def get_available_reports
281
+ # Mock data for available reports
282
+ [
283
+ {
284
+ id: 'report_001',
285
+ title: 'Android Security Analysis',
286
+ platform: 'android',
287
+ timestamp: Time.now - 3600,
288
+ risk_score: 45,
289
+ status: 'completed'
290
+ },
291
+ {
292
+ id: 'report_002',
293
+ title: 'iOS Security Analysis',
294
+ platform: 'ios',
295
+ timestamp: Time.now - 7200,
296
+ risk_score: 23,
297
+ status: 'completed'
298
+ },
299
+ {
300
+ id: 'report_003',
301
+ title: 'Cross-Platform Analysis',
302
+ platform: 'unified',
303
+ timestamp: Time.now - 10800,
304
+ risk_score: 67,
305
+ status: 'completed'
306
+ }
307
+ ]
308
+ end
309
+
310
+ def get_report_by_id(report_id)
311
+ # Mock report retrieval
312
+ reports = get_available_reports
313
+ reports.find { |r| r[:id] == report_id }
314
+ end
315
+
316
+ def get_recent_scans
317
+ # Mock recent scans data
318
+ [
319
+ {
320
+ id: 'scan_001',
321
+ platform: 'android',
322
+ timestamp: Time.now - 1800,
323
+ risk_score: 34,
324
+ device_model: 'Pixel 6'
325
+ },
326
+ {
327
+ id: 'scan_002',
328
+ platform: 'ios',
329
+ timestamp: Time.now - 3600,
330
+ risk_score: 12,
331
+ device_model: 'iPhone 13'
332
+ },
333
+ {
334
+ id: 'scan_003',
335
+ platform: 'android',
336
+ timestamp: Time.now - 5400,
337
+ risk_score: 78,
338
+ device_model: 'Samsung Galaxy S21'
339
+ }
340
+ ]
341
+ end
342
+
343
+ def determine_risk_level(score)
344
+ case score
345
+ when 0..20
346
+ 'LOW RISK'
347
+ when 21..40
348
+ 'MEDIUM RISK'
349
+ when 41..70
350
+ 'HIGH RISK'
351
+ when 71..100
352
+ 'CRITICAL RISK'
353
+ else
354
+ 'UNKNOWN'
355
+ end
356
+ end
357
+
358
+ def generate_time_labels
359
+ # Generate time labels for the last 24 hours
360
+ (0..23).map { |h| "#{h}:00" }
361
+ end
362
+
363
+ def generate_risk_timeline(results)
364
+ # Generate mock timeline data
365
+ base_score = results[:risk_score] || 0
366
+ (0..23).map { |_| base_score + rand(-10..10) }
367
+ end
368
+
369
+ def calculate_area_risk_score(area, results)
370
+ # Calculate risk score for specific security area
371
+ risk_factors = results[:risk_factors] || []
372
+
373
+ case area
374
+ when 'Authentication'
375
+ risk_factors.count { |f| f.match?(/AUTH|BIOMETRIC/) } * 10
376
+ when 'Authorization'
377
+ risk_factors.count { |f| f.match?(/PERMISSION|ACCESS/) } * 10
378
+ when 'Data Protection'
379
+ risk_factors.count { |f| f.match?(/ENCRYPTION|DATA/) } * 10
380
+ when 'Network Security'
381
+ risk_factors.count { |f| f.match?(/NETWORK|TLS|PROXY/) } * 10
382
+ when 'Code Integrity'
383
+ risk_factors.count { |f| f.match?(/INTEGRITY|SIGNING/) } * 10
384
+ when 'Runtime Protection'
385
+ risk_factors.count { |f| f.match?(/RUNTIME|RASP/) } * 10
386
+ when 'Hardware Security'
387
+ risk_factors.count { |f| f.match?(/HARDWARE|TEE/) } * 10
388
+ when 'Compliance'
389
+ risk_factors.count { |f| f.match?(/COMPLIANCE|POLICY/) } * 10
390
+ else
391
+ 0
392
+ end
393
+ end
394
+
395
+ def calculate_compliance_score(framework, results)
396
+ # Calculate compliance score for specific framework
397
+ risk_score = results[:risk_score] || 0
398
+
399
+ # Compliance score is inverse of risk score with framework-specific adjustments
400
+ base_compliance = 100 - risk_score
401
+
402
+ case framework
403
+ when 'OWASP MASVS'
404
+ [base_compliance + 10, 100].min
405
+ when 'NIST Cybersecurity'
406
+ [base_compliance + 5, 100].min
407
+ when 'ISO 27001'
408
+ base_compliance
409
+ when 'PCI DSS'
410
+ [base_compliance - 5, 0].max
411
+ when 'GDPR'
412
+ [base_compliance + 15, 100].min
413
+ when 'SOX'
414
+ [base_compliance - 10, 0].max
415
+ when 'HIPAA'
416
+ base_compliance
417
+ else
418
+ base_compliance
419
+ end
420
+ end
421
+
422
+ # Start dashboard server
423
+ def self.start_dashboard(options = {})
424
+ port = options[:port] || 4567
425
+ bind = options[:bind] || '0.0.0.0'
426
+
427
+ puts "Starting AI Root Shield Dashboard on http://#{bind}:#{port}"
428
+ puts "Dashboard features:"
429
+ puts " • Real-time security analysis"
430
+ puts " • Risk score visualization"
431
+ puts " • Compliance reporting"
432
+ puts " • Historical trend analysis"
433
+
434
+ set :port, port
435
+ set :bind, bind
436
+
437
+ run!
438
+ end
439
+ end
440
+ end
441
+ end