regscale-cli 6.27.3.0__py3-none-any.whl → 6.28.1.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.

Potentially problematic release.


This version of regscale-cli might be problematic. Click here for more details.

Files changed (113) hide show
  1. regscale/_version.py +1 -1
  2. regscale/core/app/utils/app_utils.py +11 -2
  3. regscale/dev/cli.py +26 -0
  4. regscale/dev/version.py +72 -0
  5. regscale/integrations/commercial/__init__.py +15 -1
  6. regscale/integrations/commercial/amazon/amazon/__init__.py +0 -0
  7. regscale/integrations/commercial/amazon/amazon/common.py +204 -0
  8. regscale/integrations/commercial/amazon/common.py +48 -58
  9. regscale/integrations/commercial/aws/audit_manager_compliance.py +2671 -0
  10. regscale/integrations/commercial/aws/cli.py +3093 -55
  11. regscale/integrations/commercial/aws/cloudtrail_control_mappings.py +333 -0
  12. regscale/integrations/commercial/aws/cloudtrail_evidence.py +501 -0
  13. regscale/integrations/commercial/aws/cloudwatch_control_mappings.py +357 -0
  14. regscale/integrations/commercial/aws/cloudwatch_evidence.py +490 -0
  15. regscale/integrations/commercial/aws/config_compliance.py +914 -0
  16. regscale/integrations/commercial/aws/conformance_pack_mappings.py +198 -0
  17. regscale/integrations/commercial/aws/evidence_generator.py +283 -0
  18. regscale/integrations/commercial/aws/guardduty_control_mappings.py +340 -0
  19. regscale/integrations/commercial/aws/guardduty_evidence.py +1053 -0
  20. regscale/integrations/commercial/aws/iam_control_mappings.py +368 -0
  21. regscale/integrations/commercial/aws/iam_evidence.py +574 -0
  22. regscale/integrations/commercial/aws/inventory/__init__.py +223 -22
  23. regscale/integrations/commercial/aws/inventory/base.py +107 -5
  24. regscale/integrations/commercial/aws/inventory/resources/audit_manager.py +513 -0
  25. regscale/integrations/commercial/aws/inventory/resources/cloudtrail.py +315 -0
  26. regscale/integrations/commercial/aws/inventory/resources/cloudtrail_logs_metadata.py +476 -0
  27. regscale/integrations/commercial/aws/inventory/resources/cloudwatch.py +191 -0
  28. regscale/integrations/commercial/aws/inventory/resources/compute.py +66 -9
  29. regscale/integrations/commercial/aws/inventory/resources/config.py +464 -0
  30. regscale/integrations/commercial/aws/inventory/resources/containers.py +74 -9
  31. regscale/integrations/commercial/aws/inventory/resources/database.py +106 -31
  32. regscale/integrations/commercial/aws/inventory/resources/guardduty.py +286 -0
  33. regscale/integrations/commercial/aws/inventory/resources/iam.py +470 -0
  34. regscale/integrations/commercial/aws/inventory/resources/inspector.py +476 -0
  35. regscale/integrations/commercial/aws/inventory/resources/integration.py +175 -61
  36. regscale/integrations/commercial/aws/inventory/resources/kms.py +447 -0
  37. regscale/integrations/commercial/aws/inventory/resources/networking.py +103 -67
  38. regscale/integrations/commercial/aws/inventory/resources/s3.py +394 -0
  39. regscale/integrations/commercial/aws/inventory/resources/security.py +268 -72
  40. regscale/integrations/commercial/aws/inventory/resources/securityhub.py +473 -0
  41. regscale/integrations/commercial/aws/inventory/resources/storage.py +53 -29
  42. regscale/integrations/commercial/aws/inventory/resources/systems_manager.py +657 -0
  43. regscale/integrations/commercial/aws/inventory/resources/vpc.py +655 -0
  44. regscale/integrations/commercial/aws/kms_control_mappings.py +288 -0
  45. regscale/integrations/commercial/aws/kms_evidence.py +879 -0
  46. regscale/integrations/commercial/aws/ocsf/__init__.py +7 -0
  47. regscale/integrations/commercial/aws/ocsf/constants.py +115 -0
  48. regscale/integrations/commercial/aws/ocsf/mapper.py +435 -0
  49. regscale/integrations/commercial/aws/org_control_mappings.py +286 -0
  50. regscale/integrations/commercial/aws/org_evidence.py +666 -0
  51. regscale/integrations/commercial/aws/s3_control_mappings.py +356 -0
  52. regscale/integrations/commercial/aws/s3_evidence.py +632 -0
  53. regscale/integrations/commercial/aws/scanner.py +851 -206
  54. regscale/integrations/commercial/aws/security_hub.py +319 -0
  55. regscale/integrations/commercial/aws/session_manager.py +282 -0
  56. regscale/integrations/commercial/aws/ssm_control_mappings.py +291 -0
  57. regscale/integrations/commercial/aws/ssm_evidence.py +492 -0
  58. regscale/integrations/commercial/synqly/ticketing.py +27 -0
  59. regscale/integrations/compliance_integration.py +308 -38
  60. regscale/integrations/due_date_handler.py +3 -0
  61. regscale/integrations/scanner_integration.py +399 -84
  62. regscale/models/integration_models/cisa_kev_data.json +65 -5
  63. regscale/models/integration_models/synqly_models/capabilities.json +1 -1
  64. regscale/models/integration_models/synqly_models/connectors/vulnerabilities.py +17 -9
  65. regscale/models/regscale_models/assessment.py +2 -1
  66. regscale/models/regscale_models/control_objective.py +74 -5
  67. regscale/models/regscale_models/file.py +2 -0
  68. regscale/models/regscale_models/issue.py +2 -5
  69. {regscale_cli-6.27.3.0.dist-info → regscale_cli-6.28.1.0.dist-info}/METADATA +1 -1
  70. {regscale_cli-6.27.3.0.dist-info → regscale_cli-6.28.1.0.dist-info}/RECORD +113 -34
  71. tests/regscale/integrations/commercial/aws/__init__.py +0 -0
  72. tests/regscale/integrations/commercial/aws/test_audit_manager_compliance.py +1304 -0
  73. tests/regscale/integrations/commercial/aws/test_audit_manager_evidence_aggregation.py +341 -0
  74. tests/regscale/integrations/commercial/aws/test_aws_audit_manager_collector.py +1155 -0
  75. tests/regscale/integrations/commercial/aws/test_aws_cloudtrail_collector.py +534 -0
  76. tests/regscale/integrations/commercial/aws/test_aws_config_collector.py +400 -0
  77. tests/regscale/integrations/commercial/aws/test_aws_guardduty_collector.py +315 -0
  78. tests/regscale/integrations/commercial/aws/test_aws_iam_collector.py +458 -0
  79. tests/regscale/integrations/commercial/aws/test_aws_inspector_collector.py +353 -0
  80. tests/regscale/integrations/commercial/aws/test_aws_inventory_integration.py +530 -0
  81. tests/regscale/integrations/commercial/aws/test_aws_kms_collector.py +919 -0
  82. tests/regscale/integrations/commercial/aws/test_aws_s3_collector.py +722 -0
  83. tests/regscale/integrations/commercial/aws/test_aws_scanner_integration.py +722 -0
  84. tests/regscale/integrations/commercial/aws/test_aws_securityhub_collector.py +792 -0
  85. tests/regscale/integrations/commercial/aws/test_aws_systems_manager_collector.py +918 -0
  86. tests/regscale/integrations/commercial/aws/test_aws_vpc_collector.py +996 -0
  87. tests/regscale/integrations/commercial/aws/test_cli_evidence.py +431 -0
  88. tests/regscale/integrations/commercial/aws/test_cloudtrail_control_mappings.py +452 -0
  89. tests/regscale/integrations/commercial/aws/test_cloudtrail_evidence.py +788 -0
  90. tests/regscale/integrations/commercial/aws/test_config_compliance.py +298 -0
  91. tests/regscale/integrations/commercial/aws/test_conformance_pack_mappings.py +200 -0
  92. tests/regscale/integrations/commercial/aws/test_evidence_generator.py +386 -0
  93. tests/regscale/integrations/commercial/aws/test_guardduty_control_mappings.py +564 -0
  94. tests/regscale/integrations/commercial/aws/test_guardduty_evidence.py +1041 -0
  95. tests/regscale/integrations/commercial/aws/test_iam_control_mappings.py +718 -0
  96. tests/regscale/integrations/commercial/aws/test_iam_evidence.py +1375 -0
  97. tests/regscale/integrations/commercial/aws/test_kms_control_mappings.py +656 -0
  98. tests/regscale/integrations/commercial/aws/test_kms_evidence.py +1163 -0
  99. tests/regscale/integrations/commercial/aws/test_ocsf_mapper.py +370 -0
  100. tests/regscale/integrations/commercial/aws/test_org_control_mappings.py +546 -0
  101. tests/regscale/integrations/commercial/aws/test_org_evidence.py +1240 -0
  102. tests/regscale/integrations/commercial/aws/test_s3_control_mappings.py +672 -0
  103. tests/regscale/integrations/commercial/aws/test_s3_evidence.py +987 -0
  104. tests/regscale/integrations/commercial/aws/test_scanner_evidence.py +373 -0
  105. tests/regscale/integrations/commercial/aws/test_security_hub_config_filtering.py +539 -0
  106. tests/regscale/integrations/commercial/aws/test_session_manager.py +516 -0
  107. tests/regscale/integrations/commercial/aws/test_ssm_control_mappings.py +588 -0
  108. tests/regscale/integrations/commercial/aws/test_ssm_evidence.py +735 -0
  109. tests/regscale/integrations/commercial/test_aws.py +55 -56
  110. {regscale_cli-6.27.3.0.dist-info → regscale_cli-6.28.1.0.dist-info}/LICENSE +0 -0
  111. {regscale_cli-6.27.3.0.dist-info → regscale_cli-6.28.1.0.dist-info}/WHEEL +0 -0
  112. {regscale_cli-6.27.3.0.dist-info → regscale_cli-6.28.1.0.dist-info}/entry_points.txt +0 -0
  113. {regscale_cli-6.27.3.0.dist-info → regscale_cli-6.28.1.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,340 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """AWS GuardDuty Control Mappings for RegScale Compliance Integration."""
4
+
5
+ import logging
6
+ from typing import Dict, List, Optional
7
+
8
+ logger = logging.getLogger("regscale")
9
+
10
+ # NIST 800-53 R5 Control Mappings for AWS GuardDuty
11
+ GUARDDUTY_CONTROL_MAPPINGS = {
12
+ "SI-4": {
13
+ "name": "System Monitoring",
14
+ "description": "Monitor the system to detect attacks and indicators of potential attacks",
15
+ "checks": {
16
+ "detector_enabled": {
17
+ "weight": 100,
18
+ "pass_criteria": "GuardDuty detector is enabled and actively monitoring",
19
+ "fail_criteria": "GuardDuty detector is disabled or suspended",
20
+ },
21
+ "findings_processed": {
22
+ "weight": 90,
23
+ "pass_criteria": "Active findings are reviewed and remediated",
24
+ "fail_criteria": "High severity findings remain unaddressed",
25
+ },
26
+ },
27
+ },
28
+ "IR-4": {
29
+ "name": "Incident Handling",
30
+ "description": "Implement incident handling capability for security incidents",
31
+ "checks": {
32
+ "high_severity_findings": {
33
+ "weight": 100,
34
+ "pass_criteria": "No unaddressed high severity findings",
35
+ "fail_criteria": "High severity findings detected and not remediated",
36
+ },
37
+ "incident_response": {
38
+ "weight": 90,
39
+ "pass_criteria": "Findings integrated with incident response workflow",
40
+ "fail_criteria": "Findings not tracked in incident management system",
41
+ },
42
+ },
43
+ },
44
+ "IR-5": {
45
+ "name": "Incident Monitoring",
46
+ "description": "Track and document system security incidents",
47
+ "checks": {
48
+ "finding_tracking": {
49
+ "weight": 100,
50
+ "pass_criteria": "All findings tracked and documented",
51
+ "fail_criteria": "Findings not systematically tracked",
52
+ },
53
+ },
54
+ },
55
+ "SI-3": {
56
+ "name": "Malicious Code Protection",
57
+ "description": "Implement malicious code protection mechanisms",
58
+ "checks": {
59
+ "malware_detection": {
60
+ "weight": 100,
61
+ "pass_criteria": "GuardDuty detecting and alerting on malware activities",
62
+ "fail_criteria": "Malware protection findings not enabled or monitored",
63
+ },
64
+ },
65
+ },
66
+ "RA-5": {
67
+ "name": "Vulnerability Monitoring and Scanning",
68
+ "description": "Monitor and scan for vulnerabilities in the system",
69
+ "checks": {
70
+ "threat_intelligence": {
71
+ "weight": 100,
72
+ "pass_criteria": "GuardDuty threat intelligence enabled and current",
73
+ "fail_criteria": "Threat intelligence feeds not enabled or outdated",
74
+ },
75
+ },
76
+ },
77
+ }
78
+
79
+ # Severity mapping (GuardDuty uses 0-10 scale)
80
+ SEVERITY_MAPPING = {
81
+ "LOW": (0.1, 3.9),
82
+ "MEDIUM": (4.0, 6.9),
83
+ "HIGH": (7.0, 8.9),
84
+ "CRITICAL": (9.0, 10.0),
85
+ }
86
+
87
+ # Finding types that may contain CVEs
88
+ CVE_RELATED_FINDING_TYPES = [
89
+ "UnauthorizedAccess:EC2/MaliciousIPCaller",
90
+ "CryptoCurrency:EC2/BitcoinTool",
91
+ "Trojan:EC2/",
92
+ "Backdoor:EC2/",
93
+ "Behavior:EC2/NetworkPortUnusual",
94
+ "Recon:EC2/",
95
+ ]
96
+
97
+
98
+ class GuardDutyControlMapper:
99
+ """Map AWS GuardDuty findings to compliance control status."""
100
+
101
+ def __init__(self, framework: str = "NIST800-53R5"):
102
+ """
103
+ Initialize GuardDuty control mapper.
104
+
105
+ :param str framework: Compliance framework
106
+ """
107
+ self.framework = framework
108
+ self.mappings = GUARDDUTY_CONTROL_MAPPINGS
109
+
110
+ def assess_guardduty_compliance(self, guardduty_data: Dict) -> Dict[str, str]:
111
+ """
112
+ Assess GuardDuty compliance against all mapped controls.
113
+
114
+ :param Dict guardduty_data: GuardDuty detectors and findings
115
+ :return: Dictionary mapping control IDs to compliance results (PASS/FAIL)
116
+ :rtype: Dict[str, str]
117
+ """
118
+ results = {}
119
+
120
+ if self.framework == "NIST800-53R5":
121
+ results["SI-4"] = self._assess_si4(guardduty_data)
122
+ results["IR-4"] = self._assess_ir4(guardduty_data)
123
+ results["IR-5"] = self._assess_ir5(guardduty_data)
124
+ results["SI-3"] = self._assess_si3(guardduty_data)
125
+ results["RA-5"] = self._assess_ra5(guardduty_data)
126
+
127
+ return results
128
+
129
+ def _assess_si4(self, guardduty_data: Dict) -> str:
130
+ """
131
+ Assess SI-4 (System Monitoring) compliance.
132
+
133
+ :param Dict guardduty_data: GuardDuty data
134
+ :return: Compliance result (PASS/FAIL)
135
+ :rtype: str
136
+ """
137
+ detectors = guardduty_data.get("Detectors", [])
138
+
139
+ if not detectors:
140
+ logger.debug("GuardDuty FAILS SI-4: No detectors configured")
141
+ return "FAIL"
142
+
143
+ # Check if any detector is disabled
144
+ disabled_detectors = [d for d in detectors if d.get("Status") != "ENABLED"]
145
+ if disabled_detectors:
146
+ logger.debug(f"GuardDuty FAILS SI-4: {len(disabled_detectors)} detector(s) disabled")
147
+ return "FAIL"
148
+
149
+ logger.debug(f"GuardDuty PASSES SI-4: {len(detectors)} detector(s) enabled and monitoring")
150
+ return "PASS"
151
+
152
+ def _assess_ir4(self, guardduty_data: Dict) -> str:
153
+ """
154
+ Assess IR-4 (Incident Handling) compliance.
155
+
156
+ :param Dict guardduty_data: GuardDuty data
157
+ :return: Compliance result (PASS/FAIL)
158
+ :rtype: str
159
+ """
160
+ findings = guardduty_data.get("Findings", [])
161
+
162
+ # Check for high/critical severity unaddressed findings
163
+ high_severity_findings = [
164
+ f for f in findings if self._get_severity_level(f.get("Severity", 0)) in ["HIGH", "CRITICAL"]
165
+ ]
166
+
167
+ if high_severity_findings:
168
+ logger.debug(
169
+ f"GuardDuty FAILS IR-4: {len(high_severity_findings)} high/critical severity "
170
+ "findings requiring incident response"
171
+ )
172
+ return "FAIL"
173
+
174
+ logger.debug("GuardDuty PASSES IR-4: No high severity findings requiring immediate attention")
175
+ return "PASS"
176
+
177
+ def _assess_ir5(self, guardduty_data: Dict) -> str:
178
+ """
179
+ Assess IR-5 (Incident Monitoring) compliance.
180
+
181
+ GuardDuty's active monitoring satisfies IR-5 requirements by providing continuous
182
+ security monitoring and incident detection capabilities. The presence of GuardDuty
183
+ itself, along with this integration's tracking of findings, fulfills the control.
184
+
185
+ :param Dict guardduty_data: GuardDuty data
186
+ :return: Compliance result (always PASS when GuardDuty is enabled)
187
+ :rtype: str
188
+ """
189
+ findings = guardduty_data.get("Findings", [])
190
+
191
+ # GuardDuty being active satisfies IR-5 (Incident Monitoring)
192
+ if findings:
193
+ logger.debug(f"GuardDuty PASSES IR-5: {len(findings)} findings tracked for incident monitoring")
194
+ else:
195
+ logger.debug("GuardDuty PASSES IR-5: GuardDuty monitoring active, no incidents detected")
196
+
197
+ return "PASS"
198
+
199
+ def _assess_si3(self, guardduty_data: Dict) -> str:
200
+ """
201
+ Assess SI-3 (Malicious Code Protection) compliance.
202
+
203
+ :param Dict guardduty_data: GuardDuty data
204
+ :return: Compliance result (PASS/FAIL)
205
+ :rtype: str
206
+ """
207
+ detectors = guardduty_data.get("Detectors", [])
208
+ findings = guardduty_data.get("Findings", [])
209
+
210
+ # Check if GuardDuty is enabled (provides malware detection)
211
+ if not detectors or all(d.get("Status") != "ENABLED" for d in detectors):
212
+ logger.debug("GuardDuty FAILS SI-3: No enabled detectors for malware protection")
213
+ return "FAIL"
214
+
215
+ # Check for malware-related findings
216
+ malware_findings = [f for f in findings if self._is_malware_finding(f)]
217
+
218
+ if malware_findings:
219
+ logger.warning(
220
+ f"GuardDuty malware findings detected: {len(malware_findings)} "
221
+ "potential malware activities (requires remediation)"
222
+ )
223
+
224
+ logger.debug("GuardDuty PASSES SI-3: Malware protection monitoring enabled")
225
+ return "PASS"
226
+
227
+ def _assess_ra5(self, guardduty_data: Dict) -> str:
228
+ """
229
+ Assess RA-5 (Vulnerability Monitoring) compliance.
230
+
231
+ :param Dict guardduty_data: GuardDuty data
232
+ :return: Compliance result (PASS/FAIL)
233
+ :rtype: str
234
+ """
235
+ detectors = guardduty_data.get("Detectors", [])
236
+
237
+ # Check if threat intelligence is enabled
238
+ threat_intel_enabled = any(
239
+ d.get("DataSources", {}).get("S3Logs", {}).get("Status") == "ENABLED" for d in detectors
240
+ )
241
+
242
+ if not threat_intel_enabled:
243
+ logger.debug("GuardDuty FAILS RA-5: Threat intelligence data sources not fully enabled")
244
+ return "FAIL"
245
+
246
+ logger.debug("GuardDuty PASSES RA-5: Threat intelligence and vulnerability monitoring active")
247
+ return "PASS"
248
+
249
+ def _get_severity_level(self, severity_score: float) -> str:
250
+ """
251
+ Map GuardDuty severity score to severity level.
252
+
253
+ :param float severity_score: Severity score (0-10)
254
+ :return: Severity level (LOW, MEDIUM, HIGH, CRITICAL)
255
+ :rtype: str
256
+ """
257
+ for level, (min_score, max_score) in SEVERITY_MAPPING.items():
258
+ if min_score <= severity_score <= max_score:
259
+ return level
260
+ return "LOW"
261
+
262
+ def _is_malware_finding(self, finding: Dict) -> bool:
263
+ """
264
+ Check if finding is related to malware.
265
+
266
+ :param Dict finding: GuardDuty finding
267
+ :return: True if malware-related
268
+ :rtype: bool
269
+ """
270
+ finding_type = finding.get("Type", "")
271
+ malware_indicators = [
272
+ "Trojan",
273
+ "Backdoor",
274
+ "CryptoCurrency",
275
+ "Malware",
276
+ "Bitcoin",
277
+ "CryptoCoin",
278
+ ]
279
+ return any(indicator in finding_type for indicator in malware_indicators)
280
+
281
+ def has_cve_reference(self, finding: Dict) -> bool:
282
+ """
283
+ Check if GuardDuty finding references a CVE.
284
+
285
+ :param Dict finding: GuardDuty finding
286
+ :return: True if CVE referenced
287
+ :rtype: bool
288
+ """
289
+ # Check finding description and title for CVE patterns
290
+ description = finding.get("Description", "")
291
+ title = finding.get("Title", "")
292
+ service = finding.get("Service", {})
293
+ additional_info = service.get("AdditionalInfo", {})
294
+
295
+ # CVE pattern: CVE-YYYY-NNNNN
296
+ text_to_search = f"{description} {title} {str(additional_info)}"
297
+ return "CVE-" in text_to_search.upper()
298
+
299
+ def extract_cves_from_finding(self, finding: Dict) -> List[str]:
300
+ """
301
+ Extract CVE IDs from GuardDuty finding.
302
+
303
+ :param Dict finding: GuardDuty finding
304
+ :return: List of CVE IDs
305
+ :rtype: List[str]
306
+ """
307
+ import re
308
+
309
+ cves = []
310
+ description = finding.get("Description", "")
311
+ title = finding.get("Title", "")
312
+ service = finding.get("Service", {})
313
+ additional_info = str(service.get("AdditionalInfo", {}))
314
+
315
+ text_to_search = f"{description} {title} {additional_info}"
316
+
317
+ # CVE pattern: CVE-YYYY-NNNNN
318
+ cve_pattern = r"CVE-\d{4}-\d{4,7}"
319
+ matches = re.findall(cve_pattern, text_to_search, re.IGNORECASE)
320
+
321
+ cves = list({match.upper() for match in matches})
322
+ return cves
323
+
324
+ def get_control_description(self, control_id: str) -> Optional[str]:
325
+ """Get human-readable description for a control."""
326
+ control_data = self.mappings.get(control_id)
327
+ if control_data:
328
+ return f"{control_data.get('name')}: {control_data.get('description', '')}"
329
+ return None
330
+
331
+ def get_mapped_controls(self) -> List[str]:
332
+ """Get list of all control IDs mapped for this framework."""
333
+ return list(self.mappings.keys())
334
+
335
+ def get_check_details(self, control_id: str) -> Optional[Dict]:
336
+ """Get detailed check criteria for a control."""
337
+ control_data = self.mappings.get(control_id)
338
+ if control_data:
339
+ return control_data.get("checks", {})
340
+ return None