zen-ai-pentest 2.2.0__py3-none-any.whl → 2.3.0__py3-none-any.whl
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.
- api/auth.py +61 -7
- api/csrf_protection.py +286 -0
- api/main.py +77 -11
- api/rate_limiter.py +317 -0
- api/rate_limiter_v2.py +586 -0
- autonomous/ki_analysis_agent.py +1033 -0
- benchmarks/__init__.py +12 -142
- benchmarks/agent_performance.py +374 -0
- benchmarks/api_performance.py +479 -0
- benchmarks/scan_performance.py +272 -0
- modules/agent_coordinator.py +255 -0
- modules/api_key_manager.py +501 -0
- modules/benchmark.py +706 -0
- modules/cve_updater.py +303 -0
- modules/false_positive_filter.py +149 -0
- modules/output_formats.py +1088 -0
- modules/risk_scoring.py +206 -0
- {zen_ai_pentest-2.2.0.dist-info → zen_ai_pentest-2.3.0.dist-info}/METADATA +134 -289
- {zen_ai_pentest-2.2.0.dist-info → zen_ai_pentest-2.3.0.dist-info}/RECORD +23 -9
- {zen_ai_pentest-2.2.0.dist-info → zen_ai_pentest-2.3.0.dist-info}/WHEEL +0 -0
- {zen_ai_pentest-2.2.0.dist-info → zen_ai_pentest-2.3.0.dist-info}/entry_points.txt +0 -0
- {zen_ai_pentest-2.2.0.dist-info → zen_ai_pentest-2.3.0.dist-info}/licenses/LICENSE +0 -0
- {zen_ai_pentest-2.2.0.dist-info → zen_ai_pentest-2.3.0.dist-info}/top_level.txt +0 -0
modules/risk_scoring.py
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"""Risk Scoring Module: CVSS + EPSS + Business Impact
|
|
2
|
+
|
|
3
|
+
Combines multiple risk factors for comprehensive scoring:
|
|
4
|
+
- CVSS (Common Vulnerability Scoring System)
|
|
5
|
+
- EPSS (Exploit Prediction Scoring System)
|
|
6
|
+
- Business Impact (Criticality of affected asset)
|
|
7
|
+
"""
|
|
8
|
+
from typing import Dict, List, Optional, Tuple
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
from enum import Enum
|
|
11
|
+
import math
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SeverityLevel(Enum):
|
|
15
|
+
CRITICAL = "critical"
|
|
16
|
+
HIGH = "high"
|
|
17
|
+
MEDIUM = "medium"
|
|
18
|
+
LOW = "low"
|
|
19
|
+
INFO = "info"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class RiskFactors:
|
|
24
|
+
"""Risk factors for scoring"""
|
|
25
|
+
cvss_score: float = 0.0 # 0.0 - 10.0
|
|
26
|
+
epss_score: float = 0.0 # 0.0 - 1.0 (probability)
|
|
27
|
+
business_impact: int = 1 # 1 - 5 (asset criticality)
|
|
28
|
+
exposure: int = 1 # 1 - 5 (network exposure)
|
|
29
|
+
data_sensitivity: int = 1 # 1 - 5 (data classification)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class RiskScoringModule:
|
|
33
|
+
"""Advanced risk scoring with CVSS + EPSS + Business Impact"""
|
|
34
|
+
|
|
35
|
+
name = "risk_scoring"
|
|
36
|
+
version = "1.0.0"
|
|
37
|
+
enabled = True
|
|
38
|
+
|
|
39
|
+
# Weight factors (must sum to 1.0)
|
|
40
|
+
WEIGHTS = {
|
|
41
|
+
'cvss': 0.35,
|
|
42
|
+
'epss': 0.25,
|
|
43
|
+
'business': 0.25,
|
|
44
|
+
'exposure': 0.10,
|
|
45
|
+
'data': 0.05
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
def __init__(self):
|
|
49
|
+
self.name = "risk_scoring"
|
|
50
|
+
self.enabled = True
|
|
51
|
+
|
|
52
|
+
def calculate_cvss_score(self, cve_id: str) -> float:
|
|
53
|
+
"""Fetch CVSS score from CVE database"""
|
|
54
|
+
# In production, this would query NVD API
|
|
55
|
+
# For demo, return mock scores based on CVE ID
|
|
56
|
+
cvss_map = {
|
|
57
|
+
'CVE-2021-44228': 10.0, # Log4j
|
|
58
|
+
'CVE-2024-1234': 9.8,
|
|
59
|
+
'CVE-2024-5678': 7.5,
|
|
60
|
+
'CVE-2024-9999': 5.3,
|
|
61
|
+
}
|
|
62
|
+
return cvss_map.get(cve_id, 7.0)
|
|
63
|
+
|
|
64
|
+
def calculate_epss_score(self, cve_id: str) -> float:
|
|
65
|
+
"""Fetch EPSS score (exploit probability)"""
|
|
66
|
+
# EPSS = probability of exploitation in wild
|
|
67
|
+
# In production: query EPSS API
|
|
68
|
+
epss_map = {
|
|
69
|
+
'CVE-2021-44228': 0.97, # Log4j - very likely exploited
|
|
70
|
+
'CVE-2024-1234': 0.75,
|
|
71
|
+
'CVE-2024-5678': 0.35,
|
|
72
|
+
'CVE-2024-9999': 0.10,
|
|
73
|
+
}
|
|
74
|
+
return epss_map.get(cve_id, 0.30)
|
|
75
|
+
|
|
76
|
+
def calculate_business_impact(self, asset_type: str) -> int:
|
|
77
|
+
"""Calculate business impact score (1-5)"""
|
|
78
|
+
impact_map = {
|
|
79
|
+
'production': 5,
|
|
80
|
+
'database': 5,
|
|
81
|
+
'domain_controller': 5,
|
|
82
|
+
'api_gateway': 4,
|
|
83
|
+
'web_server': 3,
|
|
84
|
+
'workstation': 2,
|
|
85
|
+
'test': 1,
|
|
86
|
+
}
|
|
87
|
+
return impact_map.get(asset_type.lower(), 3)
|
|
88
|
+
|
|
89
|
+
def calculate_composite_score(self, factors: RiskFactors) -> float:
|
|
90
|
+
"""Calculate composite risk score (0-100)"""
|
|
91
|
+
# Normalize all factors to 0-100 scale
|
|
92
|
+
cvss_normalized = factors.cvss_score * 10 # 0-10 -> 0-100
|
|
93
|
+
epss_normalized = factors.epss_score * 100 # 0-1 -> 0-100
|
|
94
|
+
business_normalized = factors.business_impact * 20 # 1-5 -> 20-100
|
|
95
|
+
exposure_normalized = factors.exposure * 20 # 1-5 -> 20-100
|
|
96
|
+
data_normalized = factors.data_sensitivity * 20 # 1-5 -> 20-100
|
|
97
|
+
|
|
98
|
+
# Weighted sum
|
|
99
|
+
score = (
|
|
100
|
+
cvss_normalized * self.WEIGHTS['cvss'] +
|
|
101
|
+
epss_normalized * self.WEIGHTS['epss'] +
|
|
102
|
+
business_normalized * self.WEIGHTS['business'] +
|
|
103
|
+
exposure_normalized * self.WEIGHTS['exposure'] +
|
|
104
|
+
data_normalized * self.WEIGHTS['data']
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
return round(score, 2)
|
|
108
|
+
|
|
109
|
+
def score_to_severity(self, score: float) -> SeverityLevel:
|
|
110
|
+
"""Convert numeric score to severity level"""
|
|
111
|
+
if score >= 80:
|
|
112
|
+
return SeverityLevel.CRITICAL
|
|
113
|
+
elif score >= 60:
|
|
114
|
+
return SeverityLevel.HIGH
|
|
115
|
+
elif score >= 40:
|
|
116
|
+
return SeverityLevel.MEDIUM
|
|
117
|
+
elif score >= 20:
|
|
118
|
+
return SeverityLevel.LOW
|
|
119
|
+
else:
|
|
120
|
+
return SeverityLevel.INFO
|
|
121
|
+
|
|
122
|
+
def score_vulnerability(
|
|
123
|
+
self,
|
|
124
|
+
cve_id: str,
|
|
125
|
+
asset_type: str = "web_server",
|
|
126
|
+
exposure: int = 3,
|
|
127
|
+
data_sensitivity: int = 3
|
|
128
|
+
) -> Dict:
|
|
129
|
+
"""Score a single vulnerability"""
|
|
130
|
+
factors = RiskFactors(
|
|
131
|
+
cvss_score=self.calculate_cvss_score(cve_id),
|
|
132
|
+
epss_score=self.calculate_epss_score(cve_id),
|
|
133
|
+
business_impact=self.calculate_business_impact(asset_type),
|
|
134
|
+
exposure=exposure,
|
|
135
|
+
data_sensitivity=data_sensitivity
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
composite_score = self.calculate_composite_score(factors)
|
|
139
|
+
severity = self.score_to_severity(composite_score)
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
'cve_id': cve_id,
|
|
143
|
+
'asset_type': asset_type,
|
|
144
|
+
'cvss_score': factors.cvss_score,
|
|
145
|
+
'epss_score': factors.epss_score,
|
|
146
|
+
'business_impact': factors.business_impact,
|
|
147
|
+
'composite_score': composite_score,
|
|
148
|
+
'severity': severity.value,
|
|
149
|
+
'priority': self._calculate_priority(composite_score, factors.epss_score),
|
|
150
|
+
'remediation_timeline': self._get_remediation_timeline(severity)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
def _calculate_priority(self, score: float, epss: float) -> str:
|
|
154
|
+
"""Calculate remediation priority"""
|
|
155
|
+
if score >= 80 and epss > 0.5:
|
|
156
|
+
return "P1 - Immediate (24h)"
|
|
157
|
+
elif score >= 60 or (score >= 40 and epss > 0.5):
|
|
158
|
+
return "P2 - High (72h)"
|
|
159
|
+
elif score >= 40:
|
|
160
|
+
return "P3 - Medium (7 days)"
|
|
161
|
+
elif score >= 20:
|
|
162
|
+
return "P4 - Low (30 days)"
|
|
163
|
+
else:
|
|
164
|
+
return "P5 - Info (next cycle)"
|
|
165
|
+
|
|
166
|
+
def _get_remediation_timeline(self, severity: SeverityLevel) -> str:
|
|
167
|
+
"""Get recommended remediation timeline"""
|
|
168
|
+
timelines = {
|
|
169
|
+
SeverityLevel.CRITICAL: "Immediate - 24 hours",
|
|
170
|
+
SeverityLevel.HIGH: "Urgent - 72 hours",
|
|
171
|
+
SeverityLevel.MEDIUM: "Standard - 7 days",
|
|
172
|
+
SeverityLevel.LOW: "Planned - 30 days",
|
|
173
|
+
SeverityLevel.INFO: "Track - Next cycle"
|
|
174
|
+
}
|
|
175
|
+
return timelines[severity]
|
|
176
|
+
|
|
177
|
+
def score_findings(
|
|
178
|
+
self,
|
|
179
|
+
findings: List[Dict],
|
|
180
|
+
asset_inventory: Optional[Dict] = None
|
|
181
|
+
) -> List[Dict]:
|
|
182
|
+
"""Score multiple findings"""
|
|
183
|
+
scored_findings = []
|
|
184
|
+
for finding in findings:
|
|
185
|
+
cve = finding.get('cve_id', 'CVE-2024-0000')
|
|
186
|
+
asset = finding.get('asset_type', 'web_server')
|
|
187
|
+
exposure = finding.get('exposure', 3)
|
|
188
|
+
data_sens = finding.get('data_sensitivity', 3)
|
|
189
|
+
|
|
190
|
+
scored = self.score_vulnerability(cve, asset, exposure, data_sens)
|
|
191
|
+
scored['original_finding'] = finding
|
|
192
|
+
scored_findings.append(scored)
|
|
193
|
+
|
|
194
|
+
# Sort by composite score (highest first)
|
|
195
|
+
scored_findings.sort(key=lambda x: x['composite_score'], reverse=True)
|
|
196
|
+
return scored_findings
|
|
197
|
+
|
|
198
|
+
def get_info(self) -> Dict:
|
|
199
|
+
"""Get module info"""
|
|
200
|
+
return {
|
|
201
|
+
'name': self.name,
|
|
202
|
+
'version': self.version,
|
|
203
|
+
'description': 'Advanced risk scoring: CVSS + EPSS + Business Impact',
|
|
204
|
+
'factors': list(self.WEIGHTS.keys()),
|
|
205
|
+
'scoring_range': '0-100'
|
|
206
|
+
}
|