ai_root_shield 0.3.0 → 0.4.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 +25 -0
- data/Gemfile.lock +1 -1
- data/README.md +58 -6
- data/examples/policies/banking_policy.json +79 -0
- data/examples/policies/development_policy.json +64 -0
- data/examples/policies/enterprise_policy.json +89 -0
- data/exe/ai_root_shield +95 -2
- data/lib/ai_root_shield/advanced_proxy_detector.rb +406 -0
- data/lib/ai_root_shield/certificate_pinning_helper.rb +258 -0
- data/lib/ai_root_shield/enterprise_policy_manager.rb +431 -0
- data/lib/ai_root_shield/version.rb +1 -1
- data/lib/ai_root_shield.rb +139 -4
- metadata +15 -5
@@ -0,0 +1,431 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
module AiRootShield
|
6
|
+
# Enterprise policy management for customizable security rules and compliance
|
7
|
+
class EnterprisePolicyManager
|
8
|
+
# Default enterprise policy template
|
9
|
+
DEFAULT_POLICY = {
|
10
|
+
"version" => "1.0",
|
11
|
+
"name" => "Default Enterprise Policy",
|
12
|
+
"description" => "Standard enterprise security policy",
|
13
|
+
"minimum_security_level" => 70,
|
14
|
+
"compliance_rules" => {
|
15
|
+
"device_requirements" => {
|
16
|
+
"allow_rooted_devices" => false,
|
17
|
+
"allow_jailbroken_devices" => false,
|
18
|
+
"allow_emulators" => false,
|
19
|
+
"require_screen_lock" => true,
|
20
|
+
"minimum_os_version" => {
|
21
|
+
"android" => "8.0",
|
22
|
+
"ios" => "12.0"
|
23
|
+
}
|
24
|
+
},
|
25
|
+
"network_security" => {
|
26
|
+
"allow_vpn" => true,
|
27
|
+
"allow_proxy" => false,
|
28
|
+
"allow_tor" => false,
|
29
|
+
"require_certificate_pinning" => true,
|
30
|
+
"allowed_dns_servers" => [],
|
31
|
+
"blocked_dns_servers" => []
|
32
|
+
},
|
33
|
+
"application_integrity" => {
|
34
|
+
"allow_debug_builds" => false,
|
35
|
+
"allow_repackaged_apps" => false,
|
36
|
+
"require_code_signing" => true,
|
37
|
+
"allowed_certificate_issuers" => []
|
38
|
+
},
|
39
|
+
"runtime_protection" => {
|
40
|
+
"enable_rasp" => true,
|
41
|
+
"allow_debugging" => false,
|
42
|
+
"allow_hooking_frameworks" => false,
|
43
|
+
"enable_tamper_detection" => true
|
44
|
+
}
|
45
|
+
},
|
46
|
+
"risk_thresholds" => {
|
47
|
+
"low" => 20,
|
48
|
+
"medium" => 50,
|
49
|
+
"high" => 70,
|
50
|
+
"critical" => 90
|
51
|
+
},
|
52
|
+
"actions" => {
|
53
|
+
"on_policy_violation" => "block",
|
54
|
+
"on_high_risk" => "alert",
|
55
|
+
"on_critical_risk" => "block",
|
56
|
+
"custom_actions" => {}
|
57
|
+
},
|
58
|
+
"reporting" => {
|
59
|
+
"enable_audit_logs" => true,
|
60
|
+
"log_level" => "info",
|
61
|
+
"retention_days" => 90
|
62
|
+
}
|
63
|
+
}.freeze
|
64
|
+
|
65
|
+
# Policy violation severity levels
|
66
|
+
VIOLATION_LEVELS = %w[info warning critical].freeze
|
67
|
+
|
68
|
+
def initialize(policy_config = nil)
|
69
|
+
@policy = load_policy(policy_config)
|
70
|
+
@violations = []
|
71
|
+
@compliance_cache = {}
|
72
|
+
@audit_logs = []
|
73
|
+
end
|
74
|
+
|
75
|
+
# Load policy from file or use provided configuration
|
76
|
+
# @param policy_source [String, Hash, nil] Policy file path, hash, or nil for default
|
77
|
+
# @return [Hash] Loaded policy
|
78
|
+
def load_policy(policy_source = nil)
|
79
|
+
case policy_source
|
80
|
+
when String
|
81
|
+
load_policy_from_file(policy_source)
|
82
|
+
when Hash
|
83
|
+
merge_with_default_policy(policy_source)
|
84
|
+
when nil
|
85
|
+
DEFAULT_POLICY.dup
|
86
|
+
else
|
87
|
+
raise ArgumentError, "Invalid policy source type: #{policy_source.class}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Validate device compliance against enterprise policy
|
92
|
+
# @param scan_result [Hash] Device scan result from AI Root Shield
|
93
|
+
# @return [Hash] Compliance validation result
|
94
|
+
def validate_compliance(scan_result)
|
95
|
+
compliance_result = {
|
96
|
+
compliant: true,
|
97
|
+
violations: [],
|
98
|
+
risk_assessment: {},
|
99
|
+
recommended_actions: [],
|
100
|
+
policy_version: @policy["version"],
|
101
|
+
validation_timestamp: Time.now.to_f
|
102
|
+
}
|
103
|
+
|
104
|
+
# Check device requirements
|
105
|
+
compliance_result = validate_device_requirements(scan_result, compliance_result)
|
106
|
+
|
107
|
+
# Check network security
|
108
|
+
compliance_result = validate_network_security(scan_result, compliance_result)
|
109
|
+
|
110
|
+
# Check application integrity
|
111
|
+
compliance_result = validate_application_integrity(scan_result, compliance_result)
|
112
|
+
|
113
|
+
# Check runtime protection
|
114
|
+
compliance_result = validate_runtime_protection(scan_result, compliance_result)
|
115
|
+
|
116
|
+
# Assess overall risk against thresholds
|
117
|
+
compliance_result = assess_risk_thresholds(scan_result, compliance_result)
|
118
|
+
|
119
|
+
# Determine final compliance status
|
120
|
+
compliance_result[:compliant] = compliance_result[:violations].empty?
|
121
|
+
|
122
|
+
# Log compliance check
|
123
|
+
log_compliance_check(scan_result, compliance_result)
|
124
|
+
|
125
|
+
compliance_result
|
126
|
+
end
|
127
|
+
|
128
|
+
# Check if minimum security level is met
|
129
|
+
# @param risk_score [Integer] Current risk score
|
130
|
+
# @return [Boolean] True if minimum security level is met
|
131
|
+
def meets_minimum_security_level?(risk_score)
|
132
|
+
minimum_level = @policy["minimum_security_level"]
|
133
|
+
(100 - risk_score) >= minimum_level
|
134
|
+
end
|
135
|
+
|
136
|
+
# Get policy configuration
|
137
|
+
# @return [Hash] Current policy configuration
|
138
|
+
def policy_configuration
|
139
|
+
@policy.dup
|
140
|
+
end
|
141
|
+
|
142
|
+
# Update policy configuration
|
143
|
+
# @param new_policy [Hash] New policy configuration
|
144
|
+
def update_policy(new_policy)
|
145
|
+
@policy = merge_with_default_policy(new_policy)
|
146
|
+
clear_compliance_cache
|
147
|
+
log_audit_event("policy_updated", "Enterprise policy configuration updated")
|
148
|
+
end
|
149
|
+
|
150
|
+
# Get compliance violations
|
151
|
+
# @return [Array<Hash>] List of compliance violations
|
152
|
+
def compliance_violations
|
153
|
+
@violations.dup
|
154
|
+
end
|
155
|
+
|
156
|
+
# Get audit logs
|
157
|
+
# @return [Array<Hash>] Audit log entries
|
158
|
+
def audit_logs
|
159
|
+
@audit_logs.dup
|
160
|
+
end
|
161
|
+
|
162
|
+
# Clear compliance cache
|
163
|
+
def clear_compliance_cache
|
164
|
+
@compliance_cache.clear
|
165
|
+
end
|
166
|
+
|
167
|
+
# Export policy to JSON
|
168
|
+
# @return [String] Policy as JSON string
|
169
|
+
def export_policy
|
170
|
+
JSON.pretty_generate(@policy)
|
171
|
+
end
|
172
|
+
|
173
|
+
# Import policy from JSON
|
174
|
+
# @param json_policy [String] Policy as JSON string
|
175
|
+
def import_policy(json_policy)
|
176
|
+
policy_hash = JSON.parse(json_policy)
|
177
|
+
update_policy(policy_hash)
|
178
|
+
end
|
179
|
+
|
180
|
+
# Get policy statistics
|
181
|
+
# @return [Hash] Policy usage statistics
|
182
|
+
def policy_statistics
|
183
|
+
{
|
184
|
+
policy_version: @policy["version"],
|
185
|
+
total_violations: @violations.size,
|
186
|
+
violation_types: @violations.group_by { |v| v[:type] }.transform_values(&:size),
|
187
|
+
compliance_checks: @compliance_cache.size,
|
188
|
+
audit_log_entries: @audit_logs.size,
|
189
|
+
last_policy_update: @audit_logs.reverse.find { |log| log[:event] == "policy_updated" }&.dig(:timestamp)
|
190
|
+
}
|
191
|
+
end
|
192
|
+
|
193
|
+
private
|
194
|
+
|
195
|
+
def load_policy_from_file(file_path)
|
196
|
+
unless File.exist?(file_path)
|
197
|
+
raise ArgumentError, "Policy file not found: #{file_path}"
|
198
|
+
end
|
199
|
+
|
200
|
+
policy_content = File.read(file_path)
|
201
|
+
policy_hash = JSON.parse(policy_content)
|
202
|
+
merge_with_default_policy(policy_hash)
|
203
|
+
rescue JSON::ParserError => e
|
204
|
+
raise ArgumentError, "Invalid JSON in policy file: #{e.message}"
|
205
|
+
end
|
206
|
+
|
207
|
+
def merge_with_default_policy(custom_policy)
|
208
|
+
# Deep merge custom policy with default policy
|
209
|
+
deep_merge(DEFAULT_POLICY.dup, custom_policy)
|
210
|
+
end
|
211
|
+
|
212
|
+
def deep_merge(hash1, hash2)
|
213
|
+
hash1.merge(hash2) do |key, old_val, new_val|
|
214
|
+
if old_val.is_a?(Hash) && new_val.is_a?(Hash)
|
215
|
+
deep_merge(old_val, new_val)
|
216
|
+
else
|
217
|
+
new_val
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def validate_device_requirements(scan_result, compliance_result)
|
223
|
+
device_rules = @policy.dig("compliance_rules", "device_requirements") || {}
|
224
|
+
|
225
|
+
# Check rooted/jailbroken devices
|
226
|
+
if !device_rules["allow_rooted_devices"] && has_root_indicators?(scan_result)
|
227
|
+
add_violation(compliance_result, "device_rooted", "critical", "Rooted device detected")
|
228
|
+
end
|
229
|
+
|
230
|
+
if !device_rules["allow_jailbroken_devices"] && has_jailbreak_indicators?(scan_result)
|
231
|
+
add_violation(compliance_result, "device_jailbroken", "critical", "Jailbroken device detected")
|
232
|
+
end
|
233
|
+
|
234
|
+
# Check emulators
|
235
|
+
if !device_rules["allow_emulators"] && has_emulator_indicators?(scan_result)
|
236
|
+
add_violation(compliance_result, "emulator_detected", "warning", "Emulator/simulator detected")
|
237
|
+
end
|
238
|
+
|
239
|
+
compliance_result
|
240
|
+
end
|
241
|
+
|
242
|
+
def validate_network_security(scan_result, compliance_result)
|
243
|
+
network_rules = @policy.dig("compliance_rules", "network_security") || {}
|
244
|
+
|
245
|
+
# Check VPN usage
|
246
|
+
if !network_rules["allow_vpn"] && has_vpn_indicators?(scan_result)
|
247
|
+
add_violation(compliance_result, "vpn_detected", "warning", "VPN usage detected")
|
248
|
+
end
|
249
|
+
|
250
|
+
# Check proxy usage
|
251
|
+
if !network_rules["allow_proxy"] && has_proxy_indicators?(scan_result)
|
252
|
+
add_violation(compliance_result, "proxy_detected", "warning", "Proxy usage detected")
|
253
|
+
end
|
254
|
+
|
255
|
+
# Check Tor usage
|
256
|
+
if !network_rules["allow_tor"] && has_tor_indicators?(scan_result)
|
257
|
+
add_violation(compliance_result, "tor_detected", "critical", "Tor usage detected")
|
258
|
+
end
|
259
|
+
|
260
|
+
compliance_result
|
261
|
+
end
|
262
|
+
|
263
|
+
def validate_application_integrity(scan_result, compliance_result)
|
264
|
+
app_rules = @policy.dig("compliance_rules", "application_integrity") || {}
|
265
|
+
|
266
|
+
# Check debug builds
|
267
|
+
if !app_rules["allow_debug_builds"] && has_debug_indicators?(scan_result)
|
268
|
+
add_violation(compliance_result, "debug_build", "warning", "Debug build detected")
|
269
|
+
end
|
270
|
+
|
271
|
+
# Check repackaged apps
|
272
|
+
if !app_rules["allow_repackaged_apps"] && has_repackaging_indicators?(scan_result)
|
273
|
+
add_violation(compliance_result, "app_repackaged", "critical", "Repackaged application detected")
|
274
|
+
end
|
275
|
+
|
276
|
+
compliance_result
|
277
|
+
end
|
278
|
+
|
279
|
+
def validate_runtime_protection(scan_result, compliance_result)
|
280
|
+
runtime_rules = @policy.dig("compliance_rules", "runtime_protection") || {}
|
281
|
+
|
282
|
+
# Check debugging
|
283
|
+
if !runtime_rules["allow_debugging"] && has_debugging_indicators?(scan_result)
|
284
|
+
add_violation(compliance_result, "debugging_detected", "critical", "Runtime debugging detected")
|
285
|
+
end
|
286
|
+
|
287
|
+
# Check hooking frameworks
|
288
|
+
if !runtime_rules["allow_hooking_frameworks"] && has_hooking_indicators?(scan_result)
|
289
|
+
add_violation(compliance_result, "hooking_detected", "critical", "Hooking framework detected")
|
290
|
+
end
|
291
|
+
|
292
|
+
compliance_result
|
293
|
+
end
|
294
|
+
|
295
|
+
def assess_risk_thresholds(scan_result, compliance_result)
|
296
|
+
risk_score = scan_result[:risk_score] || 0
|
297
|
+
thresholds = @policy["risk_thresholds"] || {}
|
298
|
+
|
299
|
+
risk_level = case risk_score
|
300
|
+
when 0..thresholds["low"]
|
301
|
+
"low"
|
302
|
+
when thresholds["low"]..thresholds["medium"]
|
303
|
+
"medium"
|
304
|
+
when thresholds["medium"]..thresholds["high"]
|
305
|
+
"high"
|
306
|
+
else
|
307
|
+
"critical"
|
308
|
+
end
|
309
|
+
|
310
|
+
compliance_result[:risk_assessment] = {
|
311
|
+
score: risk_score,
|
312
|
+
level: risk_level,
|
313
|
+
threshold_exceeded: risk_score > thresholds["high"]
|
314
|
+
}
|
315
|
+
|
316
|
+
# Add violation if risk threshold exceeded
|
317
|
+
if risk_score > thresholds["critical"]
|
318
|
+
add_violation(compliance_result, "critical_risk", "critical",
|
319
|
+
"Risk score #{risk_score} exceeds critical threshold #{thresholds['critical']}")
|
320
|
+
elsif risk_score > thresholds["high"]
|
321
|
+
add_violation(compliance_result, "high_risk", "warning",
|
322
|
+
"Risk score #{risk_score} exceeds high threshold #{thresholds['high']}")
|
323
|
+
end
|
324
|
+
|
325
|
+
compliance_result
|
326
|
+
end
|
327
|
+
|
328
|
+
def add_violation(compliance_result, type, severity, message)
|
329
|
+
violation = {
|
330
|
+
type: type,
|
331
|
+
severity: severity,
|
332
|
+
message: message,
|
333
|
+
timestamp: Time.now.to_f
|
334
|
+
}
|
335
|
+
|
336
|
+
compliance_result[:violations] << violation
|
337
|
+
@violations << violation
|
338
|
+
end
|
339
|
+
|
340
|
+
def has_root_indicators?(scan_result)
|
341
|
+
factors = scan_result[:factors] || []
|
342
|
+
factors.any? { |factor| factor.to_s.upcase.include?("ROOT") }
|
343
|
+
end
|
344
|
+
|
345
|
+
def has_jailbreak_indicators?(scan_result)
|
346
|
+
factors = scan_result[:factors] || []
|
347
|
+
factors.any? { |factor| factor.to_s.upcase.include?("JAILBREAK") || factor.to_s.upcase.include?("CYDIA") }
|
348
|
+
end
|
349
|
+
|
350
|
+
def has_emulator_indicators?(scan_result)
|
351
|
+
factors = scan_result[:factors] || []
|
352
|
+
factors.any? { |factor| factor.to_s.upcase.include?("EMULATOR") || factor.to_s.upcase.include?("SIMULATOR") }
|
353
|
+
end
|
354
|
+
|
355
|
+
def has_vpn_indicators?(scan_result)
|
356
|
+
factors = scan_result[:factors] || []
|
357
|
+
factors.any? { |factor|
|
358
|
+
factor_str = factor.to_s.upcase
|
359
|
+
factor_str.include?("VPN") || factor_str.include?("NETWORK_VPN_SERVICE_DETECTED")
|
360
|
+
}
|
361
|
+
end
|
362
|
+
|
363
|
+
def has_proxy_indicators?(scan_result)
|
364
|
+
factors = scan_result[:factors] || []
|
365
|
+
factors.any? { |factor| factor.to_s.upcase.include?("PROXY") }
|
366
|
+
end
|
367
|
+
|
368
|
+
def has_tor_indicators?(scan_result)
|
369
|
+
factors = scan_result[:factors] || []
|
370
|
+
factors.any? { |factor| factor.to_s.upcase.include?("TOR") }
|
371
|
+
end
|
372
|
+
|
373
|
+
def has_debug_indicators?(scan_result)
|
374
|
+
factors = scan_result[:factors] || []
|
375
|
+
factors.any? { |factor| factor.to_s.upcase.include?("DEBUG") }
|
376
|
+
end
|
377
|
+
|
378
|
+
def has_repackaging_indicators?(scan_result)
|
379
|
+
factors = scan_result[:factors] || []
|
380
|
+
factors.any? { |factor| factor.to_s.upcase.include?("REPACKAG") }
|
381
|
+
end
|
382
|
+
|
383
|
+
def has_debugging_indicators?(scan_result)
|
384
|
+
rasp_status = scan_result[:rasp_status] || {}
|
385
|
+
rasp_status.dig(:events_detected).to_i > 0
|
386
|
+
end
|
387
|
+
|
388
|
+
def has_hooking_indicators?(scan_result)
|
389
|
+
factors = scan_result[:factors] || []
|
390
|
+
factors.any? { |factor| factor.to_s.upcase.include?("FRIDA") || factor.to_s.upcase.include?("XPOSED") }
|
391
|
+
end
|
392
|
+
|
393
|
+
def log_compliance_check(scan_result, compliance_result)
|
394
|
+
return unless @policy.dig("reporting", "enable_audit_logs")
|
395
|
+
|
396
|
+
log_audit_event("compliance_check", "Device compliance validation performed", {
|
397
|
+
device_id: scan_result[:device_id],
|
398
|
+
risk_score: scan_result[:risk_score],
|
399
|
+
compliant: compliance_result[:compliant],
|
400
|
+
violations_count: compliance_result[:violations].size
|
401
|
+
})
|
402
|
+
|
403
|
+
# Update compliance cache for statistics
|
404
|
+
@compliance_cache[scan_result[:device_id]] = compliance_result
|
405
|
+
end
|
406
|
+
|
407
|
+
def log_audit_event(event_type, message, details = {})
|
408
|
+
return unless @policy.dig("reporting", "enable_audit_logs")
|
409
|
+
|
410
|
+
audit_entry = {
|
411
|
+
event: event_type,
|
412
|
+
message: message,
|
413
|
+
details: details,
|
414
|
+
timestamp: Time.now.to_f,
|
415
|
+
policy_version: @policy["version"]
|
416
|
+
}
|
417
|
+
|
418
|
+
@audit_logs << audit_entry
|
419
|
+
|
420
|
+
# Clean up old logs based on retention policy
|
421
|
+
cleanup_old_logs
|
422
|
+
end
|
423
|
+
|
424
|
+
def cleanup_old_logs
|
425
|
+
retention_days = @policy.dig("reporting", "retention_days") || 90
|
426
|
+
cutoff_time = Time.now.to_f - (retention_days * 24 * 60 * 60)
|
427
|
+
|
428
|
+
@audit_logs.reject! { |log| log[:timestamp] < cutoff_time }
|
429
|
+
end
|
430
|
+
end
|
431
|
+
end
|
data/lib/ai_root_shield.rb
CHANGED
@@ -11,12 +11,18 @@ require_relative "ai_root_shield/ai_behavioral_analyzer"
|
|
11
11
|
require_relative "ai_root_shield/rasp_protection"
|
12
12
|
require_relative "ai_root_shield/risk_calculator"
|
13
13
|
require_relative "ai_root_shield/device_log_parser"
|
14
|
+
require_relative "ai_root_shield/certificate_pinning_helper"
|
15
|
+
require_relative "ai_root_shield/advanced_proxy_detector"
|
16
|
+
require_relative "ai_root_shield/enterprise_policy_manager"
|
14
17
|
|
15
18
|
module AiRootShield
|
16
19
|
class Error < StandardError; end
|
17
20
|
|
18
|
-
# Global
|
21
|
+
# Global instances
|
19
22
|
@rasp_protection = nil
|
23
|
+
@policy_manager = nil
|
24
|
+
@certificate_pinning = nil
|
25
|
+
@proxy_detector = nil
|
20
26
|
|
21
27
|
# Main entry point for device scanning
|
22
28
|
# @param device_logs_path [String] Path to device logs JSON file
|
@@ -25,13 +31,26 @@ module AiRootShield
|
|
25
31
|
scan_device_with_config(device_logs_path)
|
26
32
|
end
|
27
33
|
|
28
|
-
# Scan device with custom configuration
|
34
|
+
# Scan device with custom configuration and policy validation
|
29
35
|
# @param device_logs_path [String] Path to device logs JSON file
|
30
36
|
# @param config [Hash] Configuration options
|
31
|
-
# @return [Hash] Risk assessment result with score and
|
37
|
+
# @return [Hash] Risk assessment result with score, factors, and compliance
|
32
38
|
def self.scan_device_with_config(device_logs_path, config = {})
|
33
39
|
detector = Detector.new(config)
|
34
|
-
detector.scan(device_logs_path)
|
40
|
+
scan_result = detector.scan(device_logs_path)
|
41
|
+
|
42
|
+
# Add network security analysis if enabled
|
43
|
+
if config[:enable_network_analysis]
|
44
|
+
scan_result = enhance_with_network_analysis(scan_result, config)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Add policy compliance validation if policy manager is configured
|
48
|
+
if @policy_manager
|
49
|
+
compliance_result = @policy_manager.validate_compliance(scan_result)
|
50
|
+
scan_result[:compliance] = compliance_result
|
51
|
+
end
|
52
|
+
|
53
|
+
scan_result
|
35
54
|
end
|
36
55
|
|
37
56
|
# Start RASP protection
|
@@ -49,21 +68,137 @@ module AiRootShield
|
|
49
68
|
@rasp_protection = nil
|
50
69
|
end
|
51
70
|
|
71
|
+
# Configure enterprise policy
|
72
|
+
# @param policy_config [String, Hash] Policy file path or configuration hash
|
73
|
+
# @return [EnterprisePolicyManager] Policy manager instance
|
74
|
+
def self.configure_policy(policy_config)
|
75
|
+
@policy_manager = EnterprisePolicyManager.new(policy_config)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Configure certificate pinning
|
79
|
+
# @param config [Hash] Certificate pinning configuration
|
80
|
+
# @return [CertificatePinningHelper] Certificate pinning helper instance
|
81
|
+
def self.configure_certificate_pinning(config = {})
|
82
|
+
@certificate_pinning = CertificatePinningHelper.new(config)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Configure proxy detection
|
86
|
+
# @param config [Hash] Proxy detection configuration
|
87
|
+
# @return [AdvancedProxyDetector] Proxy detector instance
|
88
|
+
def self.configure_proxy_detection(config = {})
|
89
|
+
@proxy_detector = AdvancedProxyDetector.new(config)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Validate certificate pinning for a URL
|
93
|
+
# @param url [String] URL to validate
|
94
|
+
# @return [Hash] Validation result
|
95
|
+
def self.validate_certificate_pinning(url)
|
96
|
+
return { error: "Certificate pinning not configured" } unless @certificate_pinning
|
97
|
+
|
98
|
+
cert_chain = @certificate_pinning.get_certificate_chain(url)
|
99
|
+
@certificate_pinning.validate_pin(url, cert_chain)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Detect proxy usage for an IP address
|
103
|
+
# @param ip_address [String] IP address to analyze
|
104
|
+
# @param additional_data [Hash] Additional network data
|
105
|
+
# @return [Hash] Proxy detection result
|
106
|
+
def self.detect_proxy(ip_address, additional_data = {})
|
107
|
+
return { error: "Proxy detection not configured" } unless @proxy_detector
|
108
|
+
|
109
|
+
@proxy_detector.detect_proxy(ip_address, additional_data)
|
110
|
+
end
|
111
|
+
|
52
112
|
# Get current RASP protection instance
|
53
113
|
# @return [RaspProtection, nil] Current RASP protection instance
|
54
114
|
def self.rasp_protection
|
55
115
|
@rasp_protection
|
56
116
|
end
|
57
117
|
|
118
|
+
# Get current policy manager instance
|
119
|
+
# @return [EnterprisePolicyManager, nil] Current policy manager instance
|
120
|
+
def self.policy_manager
|
121
|
+
@policy_manager
|
122
|
+
end
|
123
|
+
|
124
|
+
# Get current certificate pinning helper instance
|
125
|
+
# @return [CertificatePinningHelper, nil] Current certificate pinning helper instance
|
126
|
+
def self.certificate_pinning
|
127
|
+
@certificate_pinning
|
128
|
+
end
|
129
|
+
|
130
|
+
# Get current proxy detector instance
|
131
|
+
# @return [AdvancedProxyDetector, nil] Current proxy detector instance
|
132
|
+
def self.proxy_detector
|
133
|
+
@proxy_detector
|
134
|
+
end
|
135
|
+
|
58
136
|
# Check if RASP protection is active
|
59
137
|
# @return [Boolean] True if RASP protection is active
|
60
138
|
def self.rasp_active?
|
61
139
|
@rasp_protection&.protection_status&.dig(:active) || false
|
62
140
|
end
|
63
141
|
|
142
|
+
# Get comprehensive security status
|
143
|
+
# @return [Hash] Security status across all components
|
144
|
+
def self.security_status
|
145
|
+
{
|
146
|
+
version: VERSION,
|
147
|
+
rasp_active: rasp_active?,
|
148
|
+
policy_configured: !@policy_manager.nil?,
|
149
|
+
certificate_pinning_configured: !@certificate_pinning.nil?,
|
150
|
+
proxy_detection_configured: !@proxy_detector.nil?,
|
151
|
+
components: {
|
152
|
+
rasp: @rasp_protection&.protection_status,
|
153
|
+
policy: @policy_manager&.policy_statistics,
|
154
|
+
certificate_pinning: @certificate_pinning&.pinning_status,
|
155
|
+
proxy_detection: @proxy_detector&.detection_statistics
|
156
|
+
}
|
157
|
+
}
|
158
|
+
end
|
159
|
+
|
64
160
|
# Get version information
|
65
161
|
# @return [String] Current version
|
66
162
|
def self.version
|
67
163
|
VERSION
|
68
164
|
end
|
165
|
+
|
166
|
+
private
|
167
|
+
|
168
|
+
# Enhance scan result with network security analysis
|
169
|
+
# @param scan_result [Hash] Original scan result
|
170
|
+
# @param config [Hash] Configuration options
|
171
|
+
# @return [Hash] Enhanced scan result
|
172
|
+
def self.enhance_with_network_analysis(scan_result, config)
|
173
|
+
network_analysis = {}
|
174
|
+
|
175
|
+
# Add proxy detection if configured
|
176
|
+
if @proxy_detector && config[:target_ip]
|
177
|
+
proxy_result = @proxy_detector.detect_proxy(config[:target_ip], config[:network_data] || {})
|
178
|
+
network_analysis[:proxy_detection] = proxy_result
|
179
|
+
|
180
|
+
# Add proxy indicators to risk factors if detected
|
181
|
+
if proxy_result[:proxy_detected]
|
182
|
+
scan_result[:factors] ||= []
|
183
|
+
proxy_result[:proxy_types].each do |type|
|
184
|
+
scan_result[:factors] << "NETWORK_#{type.upcase}_DETECTED"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
# Add certificate pinning validation if configured
|
190
|
+
if @certificate_pinning && config[:target_url]
|
191
|
+
pinning_result = validate_certificate_pinning(config[:target_url])
|
192
|
+
network_analysis[:certificate_pinning] = pinning_result
|
193
|
+
|
194
|
+
# Add certificate pinning failure to risk factors if invalid
|
195
|
+
unless pinning_result[:valid]
|
196
|
+
scan_result[:factors] ||= []
|
197
|
+
scan_result[:factors] << "CERTIFICATE_PINNING_FAILED"
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
scan_result[:network_analysis] = network_analysis unless network_analysis.empty?
|
202
|
+
scan_result
|
203
|
+
end
|
69
204
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ai_root_shield
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ahmet KAHRAMAN
|
@@ -149,9 +149,12 @@ dependencies:
|
|
149
149
|
- - "~>"
|
150
150
|
- !ruby/object:Gem::Version
|
151
151
|
version: '0.9'
|
152
|
-
description: An AI-powered Ruby library that performs on-device compromise
|
153
|
-
for mobile applications
|
154
|
-
hooking
|
152
|
+
description: An AI-powered Ruby library that performs comprehensive on-device compromise
|
153
|
+
detection for mobile applications. Features include root/jailbreak detection, emulator
|
154
|
+
detection, hooking framework detection, application integrity checks, advanced network
|
155
|
+
security analysis with certificate pinning and proxy detection, enterprise policy
|
156
|
+
management, AI behavioral analysis, and RASP protection - all without requiring
|
157
|
+
a backend.
|
155
158
|
email:
|
156
159
|
- ahmetxhero@gmail.com
|
157
160
|
executables:
|
@@ -168,16 +171,22 @@ files:
|
|
168
171
|
- Rakefile
|
169
172
|
- examples/device_logs/clean_device.json
|
170
173
|
- examples/device_logs/rooted_android.json
|
174
|
+
- examples/policies/banking_policy.json
|
175
|
+
- examples/policies/development_policy.json
|
176
|
+
- examples/policies/enterprise_policy.json
|
171
177
|
- exe/ai_root_shield
|
172
178
|
- lib/ai_root_shield.rb
|
179
|
+
- lib/ai_root_shield/advanced_proxy_detector.rb
|
173
180
|
- lib/ai_root_shield/ai_behavioral_analyzer.rb
|
174
181
|
- lib/ai_root_shield/analyzers/emulator_detector.rb
|
175
182
|
- lib/ai_root_shield/analyzers/hooking_detector.rb
|
176
183
|
- lib/ai_root_shield/analyzers/integrity_checker.rb
|
177
184
|
- lib/ai_root_shield/analyzers/network_analyzer.rb
|
178
185
|
- lib/ai_root_shield/analyzers/root_detector.rb
|
186
|
+
- lib/ai_root_shield/certificate_pinning_helper.rb
|
179
187
|
- lib/ai_root_shield/detector.rb
|
180
188
|
- lib/ai_root_shield/device_log_parser.rb
|
189
|
+
- lib/ai_root_shield/enterprise_policy_manager.rb
|
181
190
|
- lib/ai_root_shield/rasp_protection.rb
|
182
191
|
- lib/ai_root_shield/risk_calculator.rb
|
183
192
|
- lib/ai_root_shield/version.rb
|
@@ -206,5 +215,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
206
215
|
requirements: []
|
207
216
|
rubygems_version: 3.6.9
|
208
217
|
specification_version: 4
|
209
|
-
summary: AI-powered mobile
|
218
|
+
summary: AI-powered mobile security library with advanced network security and enterprise
|
219
|
+
policy management
|
210
220
|
test_files: []
|