complio 0.1.1__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.
- CHANGELOG.md +208 -0
- README.md +343 -0
- complio/__init__.py +48 -0
- complio/cli/__init__.py +0 -0
- complio/cli/banner.py +87 -0
- complio/cli/commands/__init__.py +0 -0
- complio/cli/commands/history.py +439 -0
- complio/cli/commands/scan.py +700 -0
- complio/cli/main.py +115 -0
- complio/cli/output.py +338 -0
- complio/config/__init__.py +17 -0
- complio/config/settings.py +333 -0
- complio/connectors/__init__.py +9 -0
- complio/connectors/aws/__init__.py +0 -0
- complio/connectors/aws/client.py +342 -0
- complio/connectors/base.py +135 -0
- complio/core/__init__.py +10 -0
- complio/core/registry.py +228 -0
- complio/core/runner.py +351 -0
- complio/py.typed +0 -0
- complio/reporters/__init__.py +7 -0
- complio/reporters/generator.py +417 -0
- complio/tests_library/__init__.py +0 -0
- complio/tests_library/base.py +492 -0
- complio/tests_library/identity/__init__.py +0 -0
- complio/tests_library/identity/access_key_rotation.py +302 -0
- complio/tests_library/identity/mfa_enforcement.py +327 -0
- complio/tests_library/identity/root_account_protection.py +470 -0
- complio/tests_library/infrastructure/__init__.py +0 -0
- complio/tests_library/infrastructure/cloudtrail_encryption.py +286 -0
- complio/tests_library/infrastructure/cloudtrail_log_validation.py +274 -0
- complio/tests_library/infrastructure/cloudtrail_logging.py +400 -0
- complio/tests_library/infrastructure/ebs_encryption.py +244 -0
- complio/tests_library/infrastructure/ec2_security_groups.py +321 -0
- complio/tests_library/infrastructure/iam_password_policy.py +460 -0
- complio/tests_library/infrastructure/nacl_security.py +356 -0
- complio/tests_library/infrastructure/rds_encryption.py +252 -0
- complio/tests_library/infrastructure/s3_encryption.py +301 -0
- complio/tests_library/infrastructure/s3_public_access.py +369 -0
- complio/tests_library/infrastructure/secrets_manager_encryption.py +248 -0
- complio/tests_library/infrastructure/vpc_flow_logs.py +287 -0
- complio/tests_library/logging/__init__.py +0 -0
- complio/tests_library/logging/cloudwatch_alarms.py +354 -0
- complio/tests_library/logging/cloudwatch_logs_encryption.py +281 -0
- complio/tests_library/logging/cloudwatch_retention.py +252 -0
- complio/tests_library/logging/config_enabled.py +393 -0
- complio/tests_library/logging/eventbridge_rules.py +460 -0
- complio/tests_library/logging/guardduty_enabled.py +436 -0
- complio/tests_library/logging/security_hub_enabled.py +416 -0
- complio/tests_library/logging/sns_encryption.py +273 -0
- complio/tests_library/network/__init__.py +0 -0
- complio/tests_library/network/alb_nlb_security.py +421 -0
- complio/tests_library/network/api_gateway_security.py +452 -0
- complio/tests_library/network/cloudfront_https.py +332 -0
- complio/tests_library/network/direct_connect_security.py +343 -0
- complio/tests_library/network/nacl_configuration.py +367 -0
- complio/tests_library/network/network_firewall.py +355 -0
- complio/tests_library/network/transit_gateway_security.py +318 -0
- complio/tests_library/network/vpc_endpoints_security.py +339 -0
- complio/tests_library/network/vpn_security.py +333 -0
- complio/tests_library/network/waf_configuration.py +428 -0
- complio/tests_library/security/__init__.py +0 -0
- complio/tests_library/security/kms_key_rotation.py +314 -0
- complio/tests_library/storage/__init__.py +0 -0
- complio/tests_library/storage/backup_encryption.py +288 -0
- complio/tests_library/storage/dynamodb_encryption.py +280 -0
- complio/tests_library/storage/efs_encryption.py +257 -0
- complio/tests_library/storage/elasticache_encryption.py +370 -0
- complio/tests_library/storage/redshift_encryption.py +252 -0
- complio/tests_library/storage/s3_versioning.py +264 -0
- complio/utils/__init__.py +26 -0
- complio/utils/errors.py +179 -0
- complio/utils/exceptions.py +151 -0
- complio/utils/history.py +243 -0
- complio/utils/logger.py +391 -0
- complio-0.1.1.dist-info/METADATA +385 -0
- complio-0.1.1.dist-info/RECORD +79 -0
- complio-0.1.1.dist-info/WHEEL +4 -0
- complio-0.1.1.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AWS GuardDuty enabled compliance test.
|
|
3
|
+
|
|
4
|
+
Checks that AWS GuardDuty is enabled for threat detection and monitoring.
|
|
5
|
+
|
|
6
|
+
ISO 27001 Control: A.8.16 - Monitoring activities
|
|
7
|
+
Requirement: GuardDuty should be enabled for continuous security monitoring
|
|
8
|
+
|
|
9
|
+
Example:
|
|
10
|
+
>>> from complio.connectors.aws.client import AWSConnector
|
|
11
|
+
>>> from complio.tests_library.logging.guardduty_enabled import GuardDutyEnabledTest
|
|
12
|
+
>>>
|
|
13
|
+
>>> connector = AWSConnector("production", "us-east-1")
|
|
14
|
+
>>> connector.connect()
|
|
15
|
+
>>>
|
|
16
|
+
>>> test = GuardDutyEnabledTest(connector)
|
|
17
|
+
>>> result = test.run()
|
|
18
|
+
>>> print(f"Passed: {result.passed}, Score: {result.score}")
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from typing import Any, Dict
|
|
22
|
+
|
|
23
|
+
from botocore.exceptions import ClientError
|
|
24
|
+
|
|
25
|
+
from complio.connectors.aws.client import AWSConnector
|
|
26
|
+
from complio.tests_library.base import (
|
|
27
|
+
ComplianceTest,
|
|
28
|
+
Severity,
|
|
29
|
+
TestResult,
|
|
30
|
+
TestStatus,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class GuardDutyEnabledTest(ComplianceTest):
|
|
35
|
+
"""Test for AWS GuardDuty enabled compliance.
|
|
36
|
+
|
|
37
|
+
Verifies that AWS GuardDuty is properly enabled:
|
|
38
|
+
- GuardDuty detector should be enabled
|
|
39
|
+
- Should be publishing findings (not suspended)
|
|
40
|
+
- S3 Protection should be enabled
|
|
41
|
+
- EKS Protection should be enabled (if using EKS)
|
|
42
|
+
- Malware Protection should be enabled
|
|
43
|
+
|
|
44
|
+
Compliance Requirements:
|
|
45
|
+
- GuardDuty enabled in region
|
|
46
|
+
- Detector actively monitoring (not suspended)
|
|
47
|
+
- Additional protections enabled (S3, EKS, Malware)
|
|
48
|
+
- Findings published to EventBridge/SNS
|
|
49
|
+
|
|
50
|
+
Scoring:
|
|
51
|
+
- 100% if GuardDuty fully enabled with protections
|
|
52
|
+
- Partial score for basic enablement
|
|
53
|
+
- 0% if GuardDuty not enabled
|
|
54
|
+
|
|
55
|
+
Example:
|
|
56
|
+
>>> test = GuardDutyEnabledTest(connector)
|
|
57
|
+
>>> result = test.execute()
|
|
58
|
+
>>> for finding in result.findings:
|
|
59
|
+
... print(f"{finding.resource_id}: {finding.title}")
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
def __init__(self, connector: AWSConnector) -> None:
|
|
63
|
+
"""Initialize GuardDuty enabled test.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
connector: AWS connector instance
|
|
67
|
+
"""
|
|
68
|
+
super().__init__(
|
|
69
|
+
test_id="guardduty_enabled",
|
|
70
|
+
test_name="AWS GuardDuty Enabled Check",
|
|
71
|
+
description="Verify AWS GuardDuty is enabled for threat detection and monitoring",
|
|
72
|
+
control_id="A.8.16",
|
|
73
|
+
connector=connector,
|
|
74
|
+
scope="regional",
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
def execute(self) -> TestResult:
|
|
78
|
+
"""Execute GuardDuty enabled compliance test.
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
TestResult with findings if GuardDuty is not properly enabled
|
|
82
|
+
|
|
83
|
+
Example:
|
|
84
|
+
>>> test = GuardDutyEnabledTest(connector)
|
|
85
|
+
>>> result = test.execute()
|
|
86
|
+
>>> print(result.score)
|
|
87
|
+
100.0
|
|
88
|
+
"""
|
|
89
|
+
result = TestResult(
|
|
90
|
+
test_id=self.test_id,
|
|
91
|
+
test_name=self.test_name,
|
|
92
|
+
status=TestStatus.PASSED,
|
|
93
|
+
passed=True,
|
|
94
|
+
score=100.0,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
try:
|
|
98
|
+
# Get GuardDuty client
|
|
99
|
+
guardduty_client = self.connector.get_client("guardduty")
|
|
100
|
+
|
|
101
|
+
# List detectors
|
|
102
|
+
self.logger.info("listing_guardduty_detectors")
|
|
103
|
+
detectors_response = guardduty_client.list_detectors()
|
|
104
|
+
detector_ids = detectors_response.get("DetectorIds", [])
|
|
105
|
+
|
|
106
|
+
if not detector_ids:
|
|
107
|
+
self.logger.warning("no_guardduty_detectors_found")
|
|
108
|
+
|
|
109
|
+
# Create finding for GuardDuty not enabled
|
|
110
|
+
finding = self.create_finding(
|
|
111
|
+
resource_id="guardduty",
|
|
112
|
+
resource_type="guardduty_detector",
|
|
113
|
+
severity=Severity.HIGH,
|
|
114
|
+
title="AWS GuardDuty not enabled",
|
|
115
|
+
description="AWS GuardDuty is not enabled in this region. GuardDuty provides intelligent "
|
|
116
|
+
"threat detection by continuously monitoring AWS account and workload activity. "
|
|
117
|
+
"It analyzes VPC Flow Logs, CloudTrail events, and DNS logs to identify "
|
|
118
|
+
"malicious activity, unauthorized behavior, and potential security threats. "
|
|
119
|
+
"ISO 27001 A.8.16 requires monitoring of system activities for security events.",
|
|
120
|
+
remediation=(
|
|
121
|
+
"Enable AWS GuardDuty in this region:\n\n"
|
|
122
|
+
"1. Enable GuardDuty:\n"
|
|
123
|
+
"aws guardduty create-detector --enable\n\n"
|
|
124
|
+
"2. Enable additional protections:\n"
|
|
125
|
+
"# Get detector ID\n"
|
|
126
|
+
"DETECTOR_ID=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)\n\n"
|
|
127
|
+
"# Enable S3 Protection\n"
|
|
128
|
+
"aws guardduty update-detector \\\n"
|
|
129
|
+
" --detector-id $DETECTOR_ID \\\n"
|
|
130
|
+
" --data-sources S3Logs={Enable=true}\n\n"
|
|
131
|
+
"# Enable EKS Protection (if using EKS)\n"
|
|
132
|
+
"aws guardduty update-detector \\\n"
|
|
133
|
+
" --detector-id $DETECTOR_ID \\\n"
|
|
134
|
+
" --data-sources Kubernetes={AuditLogs={Enable=true}}\n\n"
|
|
135
|
+
"# Enable Malware Protection (for EBS volumes)\n"
|
|
136
|
+
"aws guardduty update-malware-protection-plan \\\n"
|
|
137
|
+
" --detector-id $DETECTOR_ID \\\n"
|
|
138
|
+
" --enable\n\n"
|
|
139
|
+
"3. Configure findings export (optional but recommended):\n"
|
|
140
|
+
"# Export to S3\n"
|
|
141
|
+
"aws guardduty create-publishing-destination \\\n"
|
|
142
|
+
" --detector-id $DETECTOR_ID \\\n"
|
|
143
|
+
" --destination-type S3 \\\n"
|
|
144
|
+
" --destination-properties \\\n"
|
|
145
|
+
" DestinationArn=arn:aws:s3:::my-guardduty-findings,\\\n"
|
|
146
|
+
" KmsKeyArn=arn:aws:kms:region:account:key/key-id\n\n"
|
|
147
|
+
"4. Set up EventBridge rule for notifications:\n"
|
|
148
|
+
"aws events put-rule \\\n"
|
|
149
|
+
" --name guardduty-findings \\\n"
|
|
150
|
+
" --event-pattern '{\n"
|
|
151
|
+
' "source": ["aws.guardduty"],\n'
|
|
152
|
+
' "detail-type": ["GuardDuty Finding"]\n'
|
|
153
|
+
" }'\n\n"
|
|
154
|
+
"# Add SNS target\n"
|
|
155
|
+
"aws events put-targets \\\n"
|
|
156
|
+
" --rule guardduty-findings \\\n"
|
|
157
|
+
" --targets Id=1,Arn=arn:aws:sns:region:account:security-alerts\n\n"
|
|
158
|
+
"Or use AWS Console:\n"
|
|
159
|
+
"1. Go to GuardDuty console\n"
|
|
160
|
+
"2. Click 'Get Started'\n"
|
|
161
|
+
"3. Click 'Enable GuardDuty'\n"
|
|
162
|
+
"4. Configure settings:\n"
|
|
163
|
+
" - Enable S3 Protection\n"
|
|
164
|
+
" - Enable EKS Protection (if applicable)\n"
|
|
165
|
+
" - Enable Malware Protection\n"
|
|
166
|
+
"5. Set up findings export:\n"
|
|
167
|
+
" - Go to Settings → Findings export options\n"
|
|
168
|
+
" - Configure S3 bucket for exports\n"
|
|
169
|
+
"6. Configure notifications:\n"
|
|
170
|
+
" - Go to EventBridge console\n"
|
|
171
|
+
" - Create rule for GuardDuty findings\n"
|
|
172
|
+
" - Add SNS topic as target\n\n"
|
|
173
|
+
"Best practices:\n"
|
|
174
|
+
"- Enable GuardDuty in all regions\n"
|
|
175
|
+
"- Use GuardDuty Organization for multi-account\n"
|
|
176
|
+
"- Configure automated responses (Lambda)\n"
|
|
177
|
+
"- Export findings to S3 for long-term storage\n"
|
|
178
|
+
"- Integrate with Security Hub\n"
|
|
179
|
+
"- Set up SNS/email notifications for high severity\n"
|
|
180
|
+
"- Review findings regularly (daily/weekly)\n"
|
|
181
|
+
"- Create suppression rules for known false positives\n"
|
|
182
|
+
"- Use Trusted IP lists for known safe IPs\n"
|
|
183
|
+
"- Use Threat IP lists for known malicious IPs\n"
|
|
184
|
+
"- Monitor GuardDuty coverage metrics\n\n"
|
|
185
|
+
"GuardDuty finding types:\n"
|
|
186
|
+
"Reconnaissance:\n"
|
|
187
|
+
"- Port scanning\n"
|
|
188
|
+
"- Unusual API calls\n"
|
|
189
|
+
"- Discovery attempts\n\n"
|
|
190
|
+
"Instance compromise:\n"
|
|
191
|
+
"- Cryptocurrency mining\n"
|
|
192
|
+
"- Backdoor communication\n"
|
|
193
|
+
"- Malware activity\n\n"
|
|
194
|
+
"Account compromise:\n"
|
|
195
|
+
"- Unusual behavior\n"
|
|
196
|
+
"- API calls from unusual locations\n"
|
|
197
|
+
"- Credential exfiltration\n\n"
|
|
198
|
+
"Bucket compromise:\n"
|
|
199
|
+
"- Suspicious S3 access\n"
|
|
200
|
+
"- Data exfiltration\n"
|
|
201
|
+
"- Policy changes\n\n"
|
|
202
|
+
"Cost considerations:\n"
|
|
203
|
+
"- Free 30-day trial\n"
|
|
204
|
+
"- Pricing based on:\n"
|
|
205
|
+
" • CloudTrail events analyzed\n"
|
|
206
|
+
" • VPC Flow Logs analyzed\n"
|
|
207
|
+
" • DNS logs analyzed\n"
|
|
208
|
+
" • S3 logs analyzed\n"
|
|
209
|
+
" • EKS logs analyzed\n"
|
|
210
|
+
"- Typically $4-5 per account per month\n"
|
|
211
|
+
"- Volume discounts available"
|
|
212
|
+
),
|
|
213
|
+
evidence=None
|
|
214
|
+
)
|
|
215
|
+
result.add_finding(finding)
|
|
216
|
+
result.score = 0.0
|
|
217
|
+
result.passed = False
|
|
218
|
+
result.status = TestStatus.FAILED
|
|
219
|
+
result.metadata = {
|
|
220
|
+
"guardduty_enabled": False,
|
|
221
|
+
"message": "GuardDuty not enabled in region"
|
|
222
|
+
}
|
|
223
|
+
return result
|
|
224
|
+
|
|
225
|
+
# Get first detector (typically only one per region)
|
|
226
|
+
detector_id = detector_ids[0]
|
|
227
|
+
result.resources_scanned += 1
|
|
228
|
+
|
|
229
|
+
# Get detector details
|
|
230
|
+
self.logger.info("getting_guardduty_detector_details", detector_id=detector_id)
|
|
231
|
+
detector_response = guardduty_client.get_detector(DetectorId=detector_id)
|
|
232
|
+
|
|
233
|
+
status = detector_response.get("Status", "")
|
|
234
|
+
finding_publishing_frequency = detector_response.get("FindingPublishingFrequency", "")
|
|
235
|
+
data_sources = detector_response.get("DataSources", {})
|
|
236
|
+
|
|
237
|
+
# Check S3 protection
|
|
238
|
+
s3_logs = data_sources.get("S3Logs", {})
|
|
239
|
+
s3_protection_enabled = s3_logs.get("Status") == "ENABLED"
|
|
240
|
+
|
|
241
|
+
# Check Kubernetes (EKS) protection
|
|
242
|
+
kubernetes = data_sources.get("Kubernetes", {})
|
|
243
|
+
eks_audit_logs = kubernetes.get("AuditLogs", {})
|
|
244
|
+
eks_protection_enabled = eks_audit_logs.get("Status") == "ENABLED"
|
|
245
|
+
|
|
246
|
+
# Check Malware protection
|
|
247
|
+
malware_protection = data_sources.get("MalwareProtection", {})
|
|
248
|
+
scan_ec2 = malware_protection.get("ScanEc2InstanceWithFindings", {})
|
|
249
|
+
malware_protection_enabled = scan_ec2.get("EbsVolumes", {}).get("Status") == "ENABLED"
|
|
250
|
+
|
|
251
|
+
# Determine issues and calculate score
|
|
252
|
+
issues = []
|
|
253
|
+
severity = Severity.MEDIUM
|
|
254
|
+
score_points = 0 # Out of 100
|
|
255
|
+
|
|
256
|
+
# Check if detector is enabled (40 points)
|
|
257
|
+
if status == "ENABLED":
|
|
258
|
+
score_points += 40
|
|
259
|
+
else:
|
|
260
|
+
issues.append(f"GuardDuty detector is {status} (not ENABLED)")
|
|
261
|
+
severity = Severity.HIGH
|
|
262
|
+
|
|
263
|
+
# Check S3 protection (20 points)
|
|
264
|
+
if s3_protection_enabled:
|
|
265
|
+
score_points += 20
|
|
266
|
+
else:
|
|
267
|
+
issues.append("S3 Protection not enabled")
|
|
268
|
+
|
|
269
|
+
# Check EKS protection (20 points - if EKS is being used)
|
|
270
|
+
# Note: This is optional as not all accounts use EKS
|
|
271
|
+
if eks_protection_enabled:
|
|
272
|
+
score_points += 20
|
|
273
|
+
# Don't penalize if not enabled, as EKS might not be used
|
|
274
|
+
|
|
275
|
+
# Check Malware protection (20 points)
|
|
276
|
+
if malware_protection_enabled:
|
|
277
|
+
score_points += 20
|
|
278
|
+
else:
|
|
279
|
+
issues.append("Malware Protection not enabled")
|
|
280
|
+
|
|
281
|
+
# Create evidence
|
|
282
|
+
evidence = self.create_evidence(
|
|
283
|
+
resource_id=detector_id,
|
|
284
|
+
resource_type="guardduty_detector",
|
|
285
|
+
data={
|
|
286
|
+
"detector_id": detector_id,
|
|
287
|
+
"status": status,
|
|
288
|
+
"finding_publishing_frequency": finding_publishing_frequency,
|
|
289
|
+
"s3_protection_enabled": s3_protection_enabled,
|
|
290
|
+
"eks_protection_enabled": eks_protection_enabled,
|
|
291
|
+
"malware_protection_enabled": malware_protection_enabled,
|
|
292
|
+
"has_issues": len(issues) > 0,
|
|
293
|
+
"issues": issues,
|
|
294
|
+
"security_score": score_points,
|
|
295
|
+
}
|
|
296
|
+
)
|
|
297
|
+
result.add_evidence(evidence)
|
|
298
|
+
|
|
299
|
+
if len(issues) > 0:
|
|
300
|
+
# Create finding for GuardDuty configuration issues
|
|
301
|
+
finding = self.create_finding(
|
|
302
|
+
resource_id=detector_id,
|
|
303
|
+
resource_type="guardduty_detector",
|
|
304
|
+
severity=severity,
|
|
305
|
+
title="AWS GuardDuty has configuration issues",
|
|
306
|
+
description=f"AWS GuardDuty detector '{detector_id}' has configuration issues: "
|
|
307
|
+
f"{'; '.join(issues)}. GuardDuty should be fully enabled with all protection "
|
|
308
|
+
"features (S3, EKS, Malware) to provide comprehensive threat detection. "
|
|
309
|
+
"ISO 27001 A.8.16 requires comprehensive monitoring of security events.",
|
|
310
|
+
remediation=(
|
|
311
|
+
f"Improve GuardDuty detector '{detector_id}' configuration:\n\n"
|
|
312
|
+
"1. Ensure detector is enabled:\n"
|
|
313
|
+
f"aws guardduty update-detector \\\n"
|
|
314
|
+
f" --detector-id {detector_id} \\\n"
|
|
315
|
+
" --enable\n\n"
|
|
316
|
+
"2. Enable S3 Protection:\n"
|
|
317
|
+
f"aws guardduty update-detector \\\n"
|
|
318
|
+
f" --detector-id {detector_id} \\\n"
|
|
319
|
+
" --data-sources S3Logs={{Enable=true}}\n\n"
|
|
320
|
+
"3. Enable EKS Protection (if using EKS):\n"
|
|
321
|
+
f"aws guardduty update-detector \\\n"
|
|
322
|
+
f" --detector-id {detector_id} \\\n"
|
|
323
|
+
" --data-sources Kubernetes={{AuditLogs={{Enable=true}}}}\n\n"
|
|
324
|
+
"4. Enable Malware Protection:\n"
|
|
325
|
+
f"aws guardduty update-malware-protection-plan \\\n"
|
|
326
|
+
f" --detector-id {detector_id} \\\n"
|
|
327
|
+
" --enable\n\n"
|
|
328
|
+
"5. Configure findings frequency:\n"
|
|
329
|
+
f"aws guardduty update-detector \\\n"
|
|
330
|
+
f" --detector-id {detector_id} \\\n"
|
|
331
|
+
" --finding-publishing-frequency FIFTEEN_MINUTES\n\n"
|
|
332
|
+
"Or use AWS Console:\n"
|
|
333
|
+
"1. Go to GuardDuty console\n"
|
|
334
|
+
"2. Click Settings\n"
|
|
335
|
+
"3. Ensure 'Status' is Enabled\n"
|
|
336
|
+
"4. Enable protection features:\n"
|
|
337
|
+
" - S3 Protection: On\n"
|
|
338
|
+
" - EKS Protection: On (if using EKS)\n"
|
|
339
|
+
" - Malware Protection: On\n"
|
|
340
|
+
"5. Set findings publishing frequency\n"
|
|
341
|
+
"6. Click 'Save'\n\n"
|
|
342
|
+
"Additional recommendations:\n"
|
|
343
|
+
"- Review GuardDuty findings regularly\n"
|
|
344
|
+
"- Set up automated remediation with Lambda\n"
|
|
345
|
+
"- Export findings to S3 for analysis\n"
|
|
346
|
+
"- Integrate with SIEM tools\n"
|
|
347
|
+
"- Create CloudWatch alarms for high severity findings"
|
|
348
|
+
),
|
|
349
|
+
evidence=evidence
|
|
350
|
+
)
|
|
351
|
+
result.add_finding(finding)
|
|
352
|
+
|
|
353
|
+
result.score = score_points
|
|
354
|
+
result.passed = score_points >= 80 # Require 80% for pass
|
|
355
|
+
result.status = TestStatus.PASSED if result.passed else TestStatus.FAILED
|
|
356
|
+
|
|
357
|
+
self.logger.warning(
|
|
358
|
+
"guardduty_has_issues",
|
|
359
|
+
detector_id=detector_id,
|
|
360
|
+
issues=issues,
|
|
361
|
+
score=score_points
|
|
362
|
+
)
|
|
363
|
+
else:
|
|
364
|
+
# GuardDuty is properly configured
|
|
365
|
+
result.score = 100.0
|
|
366
|
+
result.passed = True
|
|
367
|
+
result.status = TestStatus.PASSED
|
|
368
|
+
|
|
369
|
+
self.logger.info(
|
|
370
|
+
"guardduty_properly_configured",
|
|
371
|
+
detector_id=detector_id
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
# Add metadata
|
|
375
|
+
result.metadata = {
|
|
376
|
+
"guardduty_enabled": True,
|
|
377
|
+
"detector_id": detector_id,
|
|
378
|
+
"status": status,
|
|
379
|
+
"s3_protection": s3_protection_enabled,
|
|
380
|
+
"eks_protection": eks_protection_enabled,
|
|
381
|
+
"malware_protection": malware_protection_enabled,
|
|
382
|
+
"security_score": score_points,
|
|
383
|
+
"compliance_percentage": result.score,
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
self.logger.info(
|
|
387
|
+
"guardduty_enabled_test_completed",
|
|
388
|
+
detector_id=detector_id,
|
|
389
|
+
status=status,
|
|
390
|
+
score=result.score,
|
|
391
|
+
passed=result.passed
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
except ClientError as e:
|
|
395
|
+
error_code = e.response.get("Error", {}).get("Code")
|
|
396
|
+
self.logger.error("guardduty_enabled_test_error", error_code=error_code, error=str(e))
|
|
397
|
+
result.status = TestStatus.ERROR
|
|
398
|
+
result.passed = False
|
|
399
|
+
result.score = 0.0
|
|
400
|
+
result.error_message = f"AWS API Error: {error_code} - {str(e)}"
|
|
401
|
+
|
|
402
|
+
except Exception as e:
|
|
403
|
+
self.logger.error("guardduty_enabled_test_error", error=str(e))
|
|
404
|
+
result.status = TestStatus.ERROR
|
|
405
|
+
result.passed = False
|
|
406
|
+
result.score = 0.0
|
|
407
|
+
result.error_message = str(e)
|
|
408
|
+
|
|
409
|
+
return result
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
# ============================================================================
|
|
413
|
+
# CONVENIENCE FUNCTION
|
|
414
|
+
# ============================================================================
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
def run_guardduty_enabled_test(connector: AWSConnector) -> TestResult:
|
|
418
|
+
"""Run AWS GuardDuty enabled compliance test.
|
|
419
|
+
|
|
420
|
+
Convenience function for running the test.
|
|
421
|
+
|
|
422
|
+
Args:
|
|
423
|
+
connector: AWS connector
|
|
424
|
+
|
|
425
|
+
Returns:
|
|
426
|
+
TestResult
|
|
427
|
+
|
|
428
|
+
Example:
|
|
429
|
+
>>> from complio.connectors.aws.client import AWSConnector
|
|
430
|
+
>>> connector = AWSConnector("production", "us-east-1")
|
|
431
|
+
>>> connector.connect()
|
|
432
|
+
>>> result = run_guardduty_enabled_test(connector)
|
|
433
|
+
>>> print(f"Score: {result.score}%")
|
|
434
|
+
"""
|
|
435
|
+
test = GuardDutyEnabledTest(connector)
|
|
436
|
+
return test.execute()
|