sraverify 0.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.
- sraverify/__init__.py +36 -0
- sraverify/checks/__init__.py +56 -0
- sraverify/checks/accessanalyzer/SRA_IAA_1.py +188 -0
- sraverify/checks/accessanalyzer/SRA_IAA_2.py +162 -0
- sraverify/checks/accessanalyzer/SRA_IAA_3.py +260 -0
- sraverify/checks/accessanalyzer/SRA_IAA_4.py +207 -0
- sraverify/checks/accessanalyzer/__init__.py +3 -0
- sraverify/checks/cloudtrail/SRA-CT-1.py +220 -0
- sraverify/checks/cloudtrail/SRA-CT-10.py +229 -0
- sraverify/checks/cloudtrail/SRA-CT-11.py +242 -0
- sraverify/checks/cloudtrail/SRA-CT-12.py +163 -0
- sraverify/checks/cloudtrail/SRA-CT-13.py +279 -0
- sraverify/checks/cloudtrail/SRA-CT-2.py +218 -0
- sraverify/checks/cloudtrail/SRA-CT-3.py +196 -0
- sraverify/checks/cloudtrail/SRA-CT-4.py +161 -0
- sraverify/checks/cloudtrail/SRA-CT-5.py +200 -0
- sraverify/checks/cloudtrail/SRA-CT-6.py +161 -0
- sraverify/checks/cloudtrail/SRA-CT-7.py +194 -0
- sraverify/checks/cloudtrail/SRA-CT-8.py +226 -0
- sraverify/checks/cloudtrail/SRA-CT-9.py +226 -0
- sraverify/checks/cloudtrail/__init__.py +3 -0
- sraverify/checks/config/SRA-CONFIG-1.py +197 -0
- sraverify/checks/config/__init__.py +3 -0
- sraverify/core/__init__.py +3 -0
- sraverify/core/check.py +227 -0
- sraverify/core/logging.py +37 -0
- sraverify/core/session.py +47 -0
- sraverify/lib/__init__.py +4 -0
- sraverify/lib/audit_info.py +37 -0
- sraverify/lib/banner.py +42 -0
- sraverify/lib/check_loader.py +80 -0
- sraverify/lib/org_mgmt_checker.py +86 -0
- sraverify/lib/outputs.py +46 -0
- sraverify/lib/progress.py +75 -0
- sraverify/lib/regions.py +27 -0
- sraverify/lib/session.py +23 -0
- sraverify/main.py +350 -0
- sraverify/services/__init__.py +3 -0
- sraverify/services/accessanalyzer/__init__.py +15 -0
- sraverify/services/accessanalyzer/base.py +123 -0
- sraverify/services/accessanalyzer/checks/__init__.py +3 -0
- sraverify/services/accessanalyzer/checks/sra_accessanalyzer_01.py +82 -0
- sraverify/services/accessanalyzer/checks/sra_accessanalyzer_02.py +82 -0
- sraverify/services/accessanalyzer/checks/sra_accessanalyzer_03.py +103 -0
- sraverify/services/accessanalyzer/checks/sra_accessanalyzer_04.py +139 -0
- sraverify/services/accessanalyzer/client.py +123 -0
- sraverify/services/account/__init__.py +9 -0
- sraverify/services/account/base.py +56 -0
- sraverify/services/account/checks/__init__.py +1 -0
- sraverify/services/account/checks/sra_account_01.py +65 -0
- sraverify/services/account/checks/sra_account_02.py +63 -0
- sraverify/services/account/checks/sra_account_03.py +63 -0
- sraverify/services/account/client.py +51 -0
- sraverify/services/auditmanager/__init__.py +10 -0
- sraverify/services/auditmanager/base.py +72 -0
- sraverify/services/auditmanager/checks/__init__.py +1 -0
- sraverify/services/auditmanager/checks/sra_auditmanager_01.py +58 -0
- sraverify/services/auditmanager/checks/sra_auditmanager_02.py +80 -0
- sraverify/services/auditmanager/client.py +58 -0
- sraverify/services/cloudtrail/__init__.py +33 -0
- sraverify/services/cloudtrail/base.py +167 -0
- sraverify/services/cloudtrail/checks/__init__.py +1 -0
- sraverify/services/cloudtrail/checks/sra_cloudtrail_01.py +83 -0
- sraverify/services/cloudtrail/checks/sra_cloudtrail_02.py +99 -0
- sraverify/services/cloudtrail/checks/sra_cloudtrail_03.py +94 -0
- sraverify/services/cloudtrail/checks/sra_cloudtrail_04.py +92 -0
- sraverify/services/cloudtrail/checks/sra_cloudtrail_05.py +106 -0
- sraverify/services/cloudtrail/checks/sra_cloudtrail_06.py +93 -0
- sraverify/services/cloudtrail/checks/sra_cloudtrail_07.py +96 -0
- sraverify/services/cloudtrail/checks/sra_cloudtrail_08.py +145 -0
- sraverify/services/cloudtrail/checks/sra_cloudtrail_09.py +167 -0
- sraverify/services/cloudtrail/checks/sra_cloudtrail_10.py +162 -0
- sraverify/services/cloudtrail/checks/sra_cloudtrail_11.py +178 -0
- sraverify/services/cloudtrail/checks/sra_cloudtrail_12.py +77 -0
- sraverify/services/cloudtrail/checks/sra_cloudtrail_13.py +120 -0
- sraverify/services/cloudtrail/client.py +118 -0
- sraverify/services/config/__init__.py +25 -0
- sraverify/services/config/base.py +249 -0
- sraverify/services/config/checks/__init__.py +1 -0
- sraverify/services/config/checks/sra_config_01.py +123 -0
- sraverify/services/config/checks/sra_config_02.py +156 -0
- sraverify/services/config/checks/sra_config_03.py +149 -0
- sraverify/services/config/checks/sra_config_04.py +104 -0
- sraverify/services/config/checks/sra_config_05.py +104 -0
- sraverify/services/config/checks/sra_config_06.py +194 -0
- sraverify/services/config/checks/sra_config_07.py +162 -0
- sraverify/services/config/checks/sra_config_08.py +185 -0
- sraverify/services/config/checks/sra_config_09.py +177 -0
- sraverify/services/config/client.py +264 -0
- sraverify/services/ec2/__init__.py +8 -0
- sraverify/services/ec2/base.py +75 -0
- sraverify/services/ec2/checks/__init__.py +1 -0
- sraverify/services/ec2/checks/sra_ec2_01.py +83 -0
- sraverify/services/ec2/client.py +63 -0
- sraverify/services/firewallmanager/__init__.py +23 -0
- sraverify/services/firewallmanager/base.py +48 -0
- sraverify/services/firewallmanager/checks/__init__.py +1 -0
- sraverify/services/firewallmanager/checks/sra_firewallmanager_01.py +75 -0
- sraverify/services/firewallmanager/checks/sra_firewallmanager_02.py +57 -0
- sraverify/services/firewallmanager/checks/sra_firewallmanager_03.py +51 -0
- sraverify/services/firewallmanager/checks/sra_firewallmanager_04.py +51 -0
- sraverify/services/firewallmanager/checks/sra_firewallmanager_05.py +51 -0
- sraverify/services/firewallmanager/checks/sra_firewallmanager_06.py +51 -0
- sraverify/services/firewallmanager/checks/sra_firewallmanager_07.py +51 -0
- sraverify/services/firewallmanager/checks/sra_firewallmanager_08.py +61 -0
- sraverify/services/firewallmanager/checks/sra_firewallmanager_09.py +61 -0
- sraverify/services/firewallmanager/checks/sra_firewallmanager_10.py +71 -0
- sraverify/services/firewallmanager/client.py +40 -0
- sraverify/services/guardduty/__init__.py +58 -0
- sraverify/services/guardduty/base.py +207 -0
- sraverify/services/guardduty/checks/__init__.py +3 -0
- sraverify/services/guardduty/checks/sra_guardduty_01.py +51 -0
- sraverify/services/guardduty/checks/sra_guardduty_02.py +80 -0
- sraverify/services/guardduty/checks/sra_guardduty_03.py +77 -0
- sraverify/services/guardduty/checks/sra_guardduty_04.py +84 -0
- sraverify/services/guardduty/checks/sra_guardduty_05.py +84 -0
- sraverify/services/guardduty/checks/sra_guardduty_06.py +84 -0
- sraverify/services/guardduty/checks/sra_guardduty_07.py +85 -0
- sraverify/services/guardduty/checks/sra_guardduty_08.py +83 -0
- sraverify/services/guardduty/checks/sra_guardduty_09.py +84 -0
- sraverify/services/guardduty/checks/sra_guardduty_10.py +83 -0
- sraverify/services/guardduty/checks/sra_guardduty_11.py +93 -0
- sraverify/services/guardduty/checks/sra_guardduty_12.py +83 -0
- sraverify/services/guardduty/checks/sra_guardduty_13.py +90 -0
- sraverify/services/guardduty/checks/sra_guardduty_14.py +136 -0
- sraverify/services/guardduty/checks/sra_guardduty_15.py +94 -0
- sraverify/services/guardduty/checks/sra_guardduty_16.py +94 -0
- sraverify/services/guardduty/checks/sra_guardduty_17.py +91 -0
- sraverify/services/guardduty/checks/sra_guardduty_18.py +91 -0
- sraverify/services/guardduty/checks/sra_guardduty_19.py +91 -0
- sraverify/services/guardduty/checks/sra_guardduty_20.py +111 -0
- sraverify/services/guardduty/checks/sra_guardduty_21.py +112 -0
- sraverify/services/guardduty/checks/sra_guardduty_22.py +111 -0
- sraverify/services/guardduty/checks/sra_guardduty_23.py +154 -0
- sraverify/services/guardduty/checks/sra_guardduty_24.py +111 -0
- sraverify/services/guardduty/checks/sra_guardduty_25.py +111 -0
- sraverify/services/guardduty/client.py +107 -0
- sraverify/services/inspector/__init__.py +29 -0
- sraverify/services/inspector/base.py +233 -0
- sraverify/services/inspector/checks/__init__.py +3 -0
- sraverify/services/inspector/checks/sra_inspector_01.py +69 -0
- sraverify/services/inspector/checks/sra_inspector_02.py +68 -0
- sraverify/services/inspector/checks/sra_inspector_03.py +68 -0
- sraverify/services/inspector/checks/sra_inspector_04.py +70 -0
- sraverify/services/inspector/checks/sra_inspector_05.py +69 -0
- sraverify/services/inspector/checks/sra_inspector_06.py +115 -0
- sraverify/services/inspector/checks/sra_inspector_07.py +109 -0
- sraverify/services/inspector/checks/sra_inspector_08.py +69 -0
- sraverify/services/inspector/checks/sra_inspector_09.py +69 -0
- sraverify/services/inspector/checks/sra_inspector_10.py +69 -0
- sraverify/services/inspector/checks/sra_inspector_11.py +69 -0
- sraverify/services/inspector/client.py +99 -0
- sraverify/services/macie/__init__.py +27 -0
- sraverify/services/macie/base.py +271 -0
- sraverify/services/macie/checks/__init__.py +1 -0
- sraverify/services/macie/checks/sra_macie_01.py +100 -0
- sraverify/services/macie/checks/sra_macie_02.py +102 -0
- sraverify/services/macie/checks/sra_macie_03.py +152 -0
- sraverify/services/macie/checks/sra_macie_04.py +120 -0
- sraverify/services/macie/checks/sra_macie_05.py +85 -0
- sraverify/services/macie/checks/sra_macie_06.py +124 -0
- sraverify/services/macie/checks/sra_macie_07.py +138 -0
- sraverify/services/macie/checks/sra_macie_08.py +82 -0
- sraverify/services/macie/checks/sra_macie_09.py +103 -0
- sraverify/services/macie/checks/sra_macie_10.py +81 -0
- sraverify/services/macie/client.py +220 -0
- sraverify/services/s3/__init__.py +16 -0
- sraverify/services/s3/base.py +69 -0
- sraverify/services/s3/checks/__init__.py +1 -0
- sraverify/services/s3/checks/sra_s3_01.py +89 -0
- sraverify/services/s3/checks/sra_s3_02.py +89 -0
- sraverify/services/s3/checks/sra_s3_03.py +88 -0
- sraverify/services/s3/checks/sra_s3_04.py +88 -0
- sraverify/services/s3/client.py +52 -0
- sraverify/services/securityhub/__init__.py +27 -0
- sraverify/services/securityhub/base.py +349 -0
- sraverify/services/securityhub/checks/__init__.py +1 -0
- sraverify/services/securityhub/checks/sra_securityhub_01.py +115 -0
- sraverify/services/securityhub/checks/sra_securityhub_02.py +114 -0
- sraverify/services/securityhub/checks/sra_securityhub_03.py +136 -0
- sraverify/services/securityhub/checks/sra_securityhub_04.py +75 -0
- sraverify/services/securityhub/checks/sra_securityhub_05.py +102 -0
- sraverify/services/securityhub/checks/sra_securityhub_06.py +113 -0
- sraverify/services/securityhub/checks/sra_securityhub_07.py +121 -0
- sraverify/services/securityhub/checks/sra_securityhub_08.py +113 -0
- sraverify/services/securityhub/checks/sra_securityhub_09.py +100 -0
- sraverify/services/securityhub/checks/sra_securityhub_10.py +94 -0
- sraverify/services/securityhub/checks/sra_securityhub_11.py +73 -0
- sraverify/services/securityhub/client.py +249 -0
- sraverify/services/securityincidentresponse/__init__.py +13 -0
- sraverify/services/securityincidentresponse/base.py +95 -0
- sraverify/services/securityincidentresponse/checks/__init__.py +1 -0
- sraverify/services/securityincidentresponse/checks/sra_securityincidentresponse_01.py +77 -0
- sraverify/services/securityincidentresponse/checks/sra_securityincidentresponse_02.py +72 -0
- sraverify/services/securityincidentresponse/checks/sra_securityincidentresponse_03.py +86 -0
- sraverify/services/securityincidentresponse/checks/sra_securityincidentresponse_04.py +117 -0
- sraverify/services/securityincidentresponse/checks/sra_securityincidentresponse_05.py +55 -0
- sraverify/services/securityincidentresponse/client.py +71 -0
- sraverify/services/securitylake/__init__.py +39 -0
- sraverify/services/securitylake/base.py +461 -0
- sraverify/services/securitylake/checks/__init__.py +1 -0
- sraverify/services/securitylake/checks/sra_securitylake_01.py +98 -0
- sraverify/services/securitylake/checks/sra_securitylake_02.py +133 -0
- sraverify/services/securitylake/checks/sra_securitylake_03.py +116 -0
- sraverify/services/securitylake/checks/sra_securitylake_04.py +72 -0
- sraverify/services/securitylake/checks/sra_securitylake_05.py +116 -0
- sraverify/services/securitylake/checks/sra_securitylake_06.py +104 -0
- sraverify/services/securitylake/checks/sra_securitylake_07.py +108 -0
- sraverify/services/securitylake/checks/sra_securitylake_08.py +107 -0
- sraverify/services/securitylake/checks/sra_securitylake_09.py +107 -0
- sraverify/services/securitylake/checks/sra_securitylake_10.py +106 -0
- sraverify/services/securitylake/checks/sra_securitylake_11.py +109 -0
- sraverify/services/securitylake/checks/sra_securitylake_12.py +108 -0
- sraverify/services/securitylake/checks/sra_securitylake_13.py +108 -0
- sraverify/services/securitylake/checks/sra_securitylake_14.py +72 -0
- sraverify/services/securitylake/checks/sra_securitylake_15.py +120 -0
- sraverify/services/securitylake/checks/sra_securitylake_16.py +104 -0
- sraverify/services/securitylake/checks/sra_securitylake_17.py +103 -0
- sraverify/services/securitylake/client.py +247 -0
- sraverify/services/shield/__init__.py +33 -0
- sraverify/services/shield/base.py +199 -0
- sraverify/services/shield/checks/__init__.py +1 -0
- sraverify/services/shield/checks/sra_shield_01.py +68 -0
- sraverify/services/shield/checks/sra_shield_02.py +77 -0
- sraverify/services/shield/checks/sra_shield_03.py +84 -0
- sraverify/services/shield/checks/sra_shield_04.py +84 -0
- sraverify/services/shield/checks/sra_shield_05.py +84 -0
- sraverify/services/shield/checks/sra_shield_06.py +84 -0
- sraverify/services/shield/checks/sra_shield_07.py +84 -0
- sraverify/services/shield/checks/sra_shield_08.py +69 -0
- sraverify/services/shield/checks/sra_shield_09.py +86 -0
- sraverify/services/shield/checks/sra_shield_10.py +100 -0
- sraverify/services/shield/checks/sra_shield_11.py +71 -0
- sraverify/services/shield/checks/sra_shield_12.py +130 -0
- sraverify/services/shield/checks/sra_shield_13.py +112 -0
- sraverify/services/shield/checks/sra_shield_14.py +111 -0
- sraverify/services/shield/client.py +214 -0
- sraverify/services/waf/__init__.py +21 -0
- sraverify/services/waf/base.py +100 -0
- sraverify/services/waf/checks/__init__.py +1 -0
- sraverify/services/waf/checks/sra_waf_01.py +63 -0
- sraverify/services/waf/checks/sra_waf_02.py +82 -0
- sraverify/services/waf/checks/sra_waf_03.py +123 -0
- sraverify/services/waf/checks/sra_waf_04.py +94 -0
- sraverify/services/waf/checks/sra_waf_05.py +94 -0
- sraverify/services/waf/checks/sra_waf_06.py +91 -0
- sraverify/services/waf/checks/sra_waf_07.py +94 -0
- sraverify/services/waf/checks/sra_waf_08.py +66 -0
- sraverify/services/waf/checks/sra_waf_09.py +95 -0
- sraverify/services/waf/client.py +109 -0
- sraverify/utils/__init__.py +3 -0
- sraverify/utils/banner.py +65 -0
- sraverify/utils/outputs.py +57 -0
- sraverify/utils/progress.py +97 -0
- sraverify-0.1.0.dist-info/LICENSE +175 -0
- sraverify-0.1.0.dist-info/METADATA +516 -0
- sraverify-0.1.0.dist-info/NOTICE +1 -0
- sraverify-0.1.0.dist-info/RECORD +261 -0
- sraverify-0.1.0.dist-info/WHEEL +5 -0
- sraverify-0.1.0.dist-info/entry_points.txt +2 -0
- sraverify-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SRA-SECURITYHUB-02: Security Hub check.
|
|
3
|
+
"""
|
|
4
|
+
from typing import List, Dict, Any
|
|
5
|
+
from sraverify.services.securityhub.base import SecurityHubCheck
|
|
6
|
+
from sraverify.core.logging import logger
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SRA_SECURITYHUB_02(SecurityHubCheck):
|
|
10
|
+
"""Check if Security Hub is configured to auto-enable new security controls."""
|
|
11
|
+
|
|
12
|
+
def __init__(self):
|
|
13
|
+
"""Initialize the check."""
|
|
14
|
+
super().__init__()
|
|
15
|
+
self.check_id = "SRA-SECURITYHUB-02"
|
|
16
|
+
self.check_name = "Security Hub auto-enable new standards is enabled"
|
|
17
|
+
self.account_type = "audit" # This check is for the audit account
|
|
18
|
+
self.severity = "MEDIUM"
|
|
19
|
+
self.description = (
|
|
20
|
+
"This check verifies whether Security Hub is configured to auto-enable new security standards "
|
|
21
|
+
"as they are added to existing standards. This will ensure that as existing standards are updated "
|
|
22
|
+
"with new controls, the AWS account gets evaluated on those new controls."
|
|
23
|
+
)
|
|
24
|
+
self.check_logic = (
|
|
25
|
+
"Check evaluates if Security Hub describe organization configuration has AutoEnableStandards set to true."
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
def execute(self) -> List[Dict[str, Any]]:
|
|
29
|
+
"""
|
|
30
|
+
Execute the check.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
List of findings
|
|
34
|
+
"""
|
|
35
|
+
findings = []
|
|
36
|
+
|
|
37
|
+
# Check each region separately
|
|
38
|
+
for region in self.regions:
|
|
39
|
+
# Get organization configuration for this region
|
|
40
|
+
org_config = self.get_organization_configuration(region)
|
|
41
|
+
|
|
42
|
+
# Check if Security Hub organization configuration is available
|
|
43
|
+
if not org_config:
|
|
44
|
+
findings.append(
|
|
45
|
+
self.create_finding(
|
|
46
|
+
status="FAIL",
|
|
47
|
+
region=region,
|
|
48
|
+
resource_id=f"securityhub:configuration/{self.account_id}",
|
|
49
|
+
checked_value="Security Hub organization configuration available",
|
|
50
|
+
actual_value=f"Unable to retrieve Security Hub organization configuration in region {region}",
|
|
51
|
+
remediation="Ensure Security Hub is enabled and this account has organization admin permissions"
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
continue
|
|
55
|
+
|
|
56
|
+
# Check if using central configuration
|
|
57
|
+
org_configuration = org_config.get('OrganizationConfiguration', {})
|
|
58
|
+
config_type = org_configuration.get('ConfigurationType')
|
|
59
|
+
|
|
60
|
+
resource_id = f"securityhub:configuration/{self.account_id}"
|
|
61
|
+
|
|
62
|
+
if config_type == 'CENTRAL':
|
|
63
|
+
# In central configuration, AutoEnableStandards is always NONE
|
|
64
|
+
# This is expected behavior, so it should PASS with appropriate messaging
|
|
65
|
+
findings.append(
|
|
66
|
+
self.create_finding(
|
|
67
|
+
status="PASS",
|
|
68
|
+
region=region,
|
|
69
|
+
resource_id=resource_id,
|
|
70
|
+
checked_value="Central configuration enabled for auto-enable standards management",
|
|
71
|
+
actual_value=f"Security Hub uses central configuration [ConfigurationType: CENTRAL] in region {region}",
|
|
72
|
+
remediation="No remediation needed - central configuration manages standards automatically through configuration policies"
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
else:
|
|
76
|
+
# For local configuration, check AutoEnable and AutoEnableStandards
|
|
77
|
+
auto_enable = org_config.get('AutoEnable', False)
|
|
78
|
+
auto_enable_standards = org_config.get('AutoEnableStandards', 'NONE')
|
|
79
|
+
|
|
80
|
+
# AutoEnableStandards can be "NONE", "DEFAULT", or "NEW_CONTROLS"
|
|
81
|
+
# Both "DEFAULT" and "NEW_CONTROLS" indicate auto-enable is working
|
|
82
|
+
# "DEFAULT" means new controls in existing standards are auto-enabled
|
|
83
|
+
# "NEW_CONTROLS" means new controls are auto-enabled (newer API version)
|
|
84
|
+
auto_enable_new_controls = auto_enable_standards in ['DEFAULT', 'NEW_CONTROLS']
|
|
85
|
+
|
|
86
|
+
if not auto_enable or not auto_enable_new_controls:
|
|
87
|
+
findings.append(
|
|
88
|
+
self.create_finding(
|
|
89
|
+
status="FAIL",
|
|
90
|
+
region=region,
|
|
91
|
+
resource_id=resource_id,
|
|
92
|
+
checked_value="AutoEnable: true, AutoEnableStandards: DEFAULT or NEW_CONTROLS",
|
|
93
|
+
actual_value=f"Security Hub auto-enable configuration [AutoEnable: {auto_enable}, AutoEnableStandards: {auto_enable_standards}] in region {region}",
|
|
94
|
+
remediation=(
|
|
95
|
+
"Enable auto-enable new controls in Security Hub. In the Security Hub console, "
|
|
96
|
+
"navigate to Settings > General > Configuration > Auto-enable new controls, and enable this setting. "
|
|
97
|
+
"Alternatively, use the AWS CLI command: "
|
|
98
|
+
f"aws securityhub update-organization-configuration --auto-enable --auto-enable-standards DEFAULT --region {region}"
|
|
99
|
+
)
|
|
100
|
+
)
|
|
101
|
+
)
|
|
102
|
+
else:
|
|
103
|
+
findings.append(
|
|
104
|
+
self.create_finding(
|
|
105
|
+
status="PASS",
|
|
106
|
+
region=region,
|
|
107
|
+
resource_id=resource_id,
|
|
108
|
+
checked_value="AutoEnable: true, AutoEnableStandards: DEFAULT or NEW_CONTROLS",
|
|
109
|
+
actual_value=f"Security Hub auto-enable is properly configured [AutoEnable: {auto_enable}, AutoEnableStandards: {auto_enable_standards}] in region {region}",
|
|
110
|
+
remediation="No remediation needed"
|
|
111
|
+
)
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
return findings
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SRA-SECURITYHUB-03: Security Hub check.
|
|
3
|
+
"""
|
|
4
|
+
from typing import List, Dict, Any
|
|
5
|
+
from sraverify.services.securityhub.base import SecurityHubCheck
|
|
6
|
+
from sraverify.core.logging import logger
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SRA_SECURITYHUB_03(SecurityHubCheck):
|
|
10
|
+
"""Check if Security Hub administration for the account matches delegated administrator."""
|
|
11
|
+
|
|
12
|
+
def __init__(self):
|
|
13
|
+
"""Initialize the check."""
|
|
14
|
+
super().__init__()
|
|
15
|
+
self.check_id = "SRA-SECURITYHUB-03"
|
|
16
|
+
self.check_name = "Security Hub administration for the account matches delegated administrator"
|
|
17
|
+
self.account_type = "management" # This check is for the management account
|
|
18
|
+
self.severity = "HIGH"
|
|
19
|
+
self.description = (
|
|
20
|
+
"This check verifies whether Security Hub service administration for the AWS account is set to "
|
|
21
|
+
"AWS Organization delegated admin account for Security Hub."
|
|
22
|
+
)
|
|
23
|
+
self.check_logic = (
|
|
24
|
+
"Check evaluates securityhub list-organization-admin-accounts and organizations list-delegated-administrators "
|
|
25
|
+
"--service-principal securityhub.amazonaws.com. Check PASS if AccountID and ID returned are the same."
|
|
26
|
+
)
|
|
27
|
+
self._audit_accounts = [] # Will be populated from command line args
|
|
28
|
+
|
|
29
|
+
def execute(self) -> List[Dict[str, Any]]:
|
|
30
|
+
"""
|
|
31
|
+
Execute the check.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
List of findings
|
|
35
|
+
"""
|
|
36
|
+
findings = []
|
|
37
|
+
|
|
38
|
+
# We only need to check one region for this
|
|
39
|
+
region = self.regions[0]
|
|
40
|
+
|
|
41
|
+
# Get delegated administrators for Security Hub
|
|
42
|
+
delegated_admins = self.get_delegated_administrators(region)
|
|
43
|
+
|
|
44
|
+
# Get organization admin accounts
|
|
45
|
+
org_admin_accounts = self.get_organization_admin_accounts(region)
|
|
46
|
+
|
|
47
|
+
resource_id = f"delegated-admin/{self.account_id}"
|
|
48
|
+
|
|
49
|
+
# Check if there are any delegated administrators
|
|
50
|
+
if not delegated_admins:
|
|
51
|
+
# Format the actual value properly
|
|
52
|
+
actual_value = 'aws organizations list-delegated-administrators --service-principal securityhub.amazonaws.com - No delegated administrators found'
|
|
53
|
+
|
|
54
|
+
findings.append(
|
|
55
|
+
self.create_finding(
|
|
56
|
+
status="FAIL",
|
|
57
|
+
region="global",
|
|
58
|
+
resource_id=resource_id,
|
|
59
|
+
checked_value="Security Hub delegated administrator matches organization admin account",
|
|
60
|
+
actual_value=actual_value,
|
|
61
|
+
remediation=(
|
|
62
|
+
"Register a delegated administrator for Security Hub. In the AWS Console, navigate to "
|
|
63
|
+
"Organizations, go to Services, find Security Hub, and register a delegated administrator. "
|
|
64
|
+
"Alternatively, use the AWS CLI command: "
|
|
65
|
+
"aws organizations register-delegated-administrator --account-id [AUDIT_ACCOUNT_ID] "
|
|
66
|
+
"--service-principal securityhub.amazonaws.com"
|
|
67
|
+
)
|
|
68
|
+
)
|
|
69
|
+
)
|
|
70
|
+
return findings
|
|
71
|
+
|
|
72
|
+
# Check if there are any organization admin accounts
|
|
73
|
+
if not org_admin_accounts:
|
|
74
|
+
# Format the actual value properly
|
|
75
|
+
actual_value = 'aws securityhub list-organization-admin-accounts - No Security Hub admin account found'
|
|
76
|
+
|
|
77
|
+
findings.append(
|
|
78
|
+
self.create_finding(
|
|
79
|
+
status="FAIL",
|
|
80
|
+
region="global",
|
|
81
|
+
resource_id=resource_id,
|
|
82
|
+
checked_value="Security Hub delegated administrator matches organization admin account",
|
|
83
|
+
actual_value=actual_value,
|
|
84
|
+
remediation=(
|
|
85
|
+
"Enable a Security Hub administrator account. In the AWS Console, navigate to Security Hub "
|
|
86
|
+
"in the management account, go to Settings > General, and set the administrator account. "
|
|
87
|
+
"Alternatively, use the AWS CLI command: "
|
|
88
|
+
"aws securityhub enable-organization-admin-account --admin-account-id [ADMIN_ID]"
|
|
89
|
+
)
|
|
90
|
+
)
|
|
91
|
+
)
|
|
92
|
+
return findings
|
|
93
|
+
|
|
94
|
+
# Get the delegated admin ID and organization admin ID
|
|
95
|
+
delegated_admin_id = delegated_admins[0].get('Id') if delegated_admins else None
|
|
96
|
+
org_admin_id = org_admin_accounts[0].get('AccountId') if org_admin_accounts else None
|
|
97
|
+
|
|
98
|
+
# Format the actual values properly
|
|
99
|
+
delegated_admin_value = f'aws organizations list-delegated-administrators --service-principal securityhub.amazonaws.com - "DelegatedAdministrators": "Id": "{delegated_admin_id}"'
|
|
100
|
+
org_admin_value = f'aws securityhub list-organization-admin-accounts - "AdminAccounts": "AccountId": "{org_admin_id}"'
|
|
101
|
+
|
|
102
|
+
# Check if they match
|
|
103
|
+
if delegated_admin_id and org_admin_id and delegated_admin_id == org_admin_id:
|
|
104
|
+
findings.append(
|
|
105
|
+
self.create_finding(
|
|
106
|
+
status="PASS",
|
|
107
|
+
region="global",
|
|
108
|
+
resource_id=resource_id,
|
|
109
|
+
checked_value="Security Hub delegated administrator matches organization admin account",
|
|
110
|
+
actual_value=f"{delegated_admin_value} matches {org_admin_value}",
|
|
111
|
+
remediation="No remediation needed"
|
|
112
|
+
)
|
|
113
|
+
)
|
|
114
|
+
else:
|
|
115
|
+
findings.append(
|
|
116
|
+
self.create_finding(
|
|
117
|
+
status="FAIL",
|
|
118
|
+
region="global",
|
|
119
|
+
resource_id=resource_id,
|
|
120
|
+
checked_value="Security Hub delegated administrator matches organization admin account",
|
|
121
|
+
actual_value=f"{delegated_admin_value} does not match {org_admin_value}",
|
|
122
|
+
remediation=(
|
|
123
|
+
"Update the Security Hub delegated administrator and organization admin account to match. "
|
|
124
|
+
"First, deregister the current delegated administrator using: "
|
|
125
|
+
f"aws organizations deregister-delegated-administrator --account-id {delegated_admin_id} "
|
|
126
|
+
"--service-principal securityhub.amazonaws.com\n"
|
|
127
|
+
"Then, register the correct account as the delegated administrator using: "
|
|
128
|
+
"aws organizations register-delegated-administrator --account-id [CORRECT_ACCOUNT_ID] "
|
|
129
|
+
"--service-principal securityhub.amazonaws.com\n"
|
|
130
|
+
"Finally, enable the same account as the Security Hub administrator using: "
|
|
131
|
+
"aws securityhub enable-organization-admin-account --admin-account-id [CORRECT_ACCOUNT_ID]"
|
|
132
|
+
)
|
|
133
|
+
)
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
return findings
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SRA-SECURITYHUB-04: Security Hub check.
|
|
3
|
+
"""
|
|
4
|
+
from typing import List, Dict, Any
|
|
5
|
+
from sraverify.services.securityhub.base import SecurityHubCheck
|
|
6
|
+
from sraverify.core.logging import logger
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SRA_SECURITYHUB_04(SecurityHubCheck):
|
|
10
|
+
"""Check if Security Hub central configuration is enabled."""
|
|
11
|
+
|
|
12
|
+
def __init__(self):
|
|
13
|
+
"""Initialize the check."""
|
|
14
|
+
super().__init__()
|
|
15
|
+
self.check_id = "SRA-SECURITYHUB-04"
|
|
16
|
+
self.check_name = "Security Hub central configuration is enabled"
|
|
17
|
+
self.account_type = "audit"
|
|
18
|
+
self.severity = "HIGH"
|
|
19
|
+
self.description = (
|
|
20
|
+
"This check verifies whether Security Hub is configured for central configuration. "
|
|
21
|
+
"Central configuration allows the delegated administrator to manage Security Hub, "
|
|
22
|
+
"standards, and controls across all organization accounts from a single location."
|
|
23
|
+
)
|
|
24
|
+
self.check_logic = (
|
|
25
|
+
"Check evaluates if Security Hub organization configuration has ConfigurationType "
|
|
26
|
+
"set to CENTRAL and Status set to ENABLED in the delegated administrator account in all regions."
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
def execute(self) -> List[Dict[str, Any]]:
|
|
30
|
+
"""
|
|
31
|
+
Execute the check.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
List of findings
|
|
35
|
+
"""
|
|
36
|
+
findings = []
|
|
37
|
+
|
|
38
|
+
for region in self.regions:
|
|
39
|
+
org_config = self.get_organization_configuration(region)
|
|
40
|
+
|
|
41
|
+
org_configuration = org_config.get('OrganizationConfiguration', {})
|
|
42
|
+
config_type = org_configuration.get('ConfigurationType')
|
|
43
|
+
status = org_configuration.get('Status')
|
|
44
|
+
|
|
45
|
+
resource_id = f"securityhub:hub/{self.account_id}"
|
|
46
|
+
|
|
47
|
+
if config_type != 'CENTRAL' or status != 'ENABLED':
|
|
48
|
+
findings.append(
|
|
49
|
+
self.create_finding(
|
|
50
|
+
status="FAIL",
|
|
51
|
+
region=region,
|
|
52
|
+
resource_id=resource_id,
|
|
53
|
+
checked_value="OrganizationConfiguration Configuration Type is Central and Status Enabled",
|
|
54
|
+
actual_value=f"Security Hub delegated admin {self.account_id} is not setup properly to view findings for associated member accounts via ConfigurationType:{config_type} and Status:{status} in region {region}",
|
|
55
|
+
remediation=(
|
|
56
|
+
"Configure Security Hub with central configuration. In the Security Hub delegated admin account, "
|
|
57
|
+
"navigate to Settings > General > Configuration and select 'Centrally manage Security Hub across all accounts in your organization'. "
|
|
58
|
+
"Alternatively, use the AWS CLI command: "
|
|
59
|
+
f"aws securityhub update-organization-configuration --organization-configuration ConfigurationType=CENTRAL --region {region}"
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
)
|
|
63
|
+
else:
|
|
64
|
+
findings.append(
|
|
65
|
+
self.create_finding(
|
|
66
|
+
status="PASS",
|
|
67
|
+
region=region,
|
|
68
|
+
resource_id=resource_id,
|
|
69
|
+
checked_value="OrganizationConfiguration Configuration Type is Central and Status Enabled",
|
|
70
|
+
actual_value=f"Security Hub delegated admin {self.account_id} is setup properly to view findings for associated member accounts via ConfigurationType:{config_type} and Status:{status} in region {region}",
|
|
71
|
+
remediation="No remediation needed"
|
|
72
|
+
)
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
return findings
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SRA-SECURITYHUB-05: Security Hub check.
|
|
3
|
+
"""
|
|
4
|
+
from typing import List, Dict, Any
|
|
5
|
+
from sraverify.services.securityhub.base import SecurityHubCheck
|
|
6
|
+
from sraverify.core.logging import logger
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SRA_SECURITYHUB_05(SecurityHubCheck):
|
|
10
|
+
"""Check if Security Hub has integrations with findings generating products."""
|
|
11
|
+
|
|
12
|
+
def __init__(self):
|
|
13
|
+
"""Initialize the check."""
|
|
14
|
+
super().__init__()
|
|
15
|
+
self.check_id = "SRA-SECURITYHUB-05"
|
|
16
|
+
self.check_name = "Security Hub integration with findings generating products"
|
|
17
|
+
self.account_type = "audit" # This check is for the audit account
|
|
18
|
+
self.severity = "MEDIUM"
|
|
19
|
+
self.description = (
|
|
20
|
+
"This check verifies whether Security Hub has expected integration with AWS services "
|
|
21
|
+
"and third party products to ingest security findings."
|
|
22
|
+
)
|
|
23
|
+
self.check_logic = (
|
|
24
|
+
"Check looks in audit account to evaluate see what types of findings are being ingested. "
|
|
25
|
+
"PASS if there are any products listed."
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
def execute(self) -> List[Dict[str, Any]]:
|
|
29
|
+
"""
|
|
30
|
+
Execute the check.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
List of findings
|
|
34
|
+
"""
|
|
35
|
+
findings = []
|
|
36
|
+
|
|
37
|
+
# Check each region separately
|
|
38
|
+
for region in self.regions:
|
|
39
|
+
# Get enabled products for import in this specific region
|
|
40
|
+
enabled_products = self.get_enabled_products_for_import(region)
|
|
41
|
+
|
|
42
|
+
resource_id = f"securityhub:integrations/{self.account_id}"
|
|
43
|
+
|
|
44
|
+
# Check if Security Hub is not enabled (None response)
|
|
45
|
+
if enabled_products is None:
|
|
46
|
+
findings.append(
|
|
47
|
+
self.create_finding(
|
|
48
|
+
status="FAIL",
|
|
49
|
+
region=region,
|
|
50
|
+
resource_id=resource_id,
|
|
51
|
+
checked_value="Security Hub enabled with product integrations",
|
|
52
|
+
actual_value=f"Security Hub is not enabled in region {region}",
|
|
53
|
+
remediation=(
|
|
54
|
+
f"Enable Security Hub in region {region} first. "
|
|
55
|
+
"Use the AWS CLI command: "
|
|
56
|
+
f"aws securityhub enable-security-hub --region {region}, "
|
|
57
|
+
"then configure product integrations."
|
|
58
|
+
)
|
|
59
|
+
)
|
|
60
|
+
)
|
|
61
|
+
elif not enabled_products:
|
|
62
|
+
# Security Hub is enabled but no products configured
|
|
63
|
+
findings.append(
|
|
64
|
+
self.create_finding(
|
|
65
|
+
status="FAIL",
|
|
66
|
+
region=region,
|
|
67
|
+
resource_id=resource_id,
|
|
68
|
+
checked_value="List of products that are enabled in Security Hub",
|
|
69
|
+
actual_value=f"Security Hub has no enabled security integrations in region {region}",
|
|
70
|
+
remediation=(
|
|
71
|
+
"Enable integrations with security findings generating products. In the Security Hub console, "
|
|
72
|
+
"navigate to Integrations and enable relevant AWS services like GuardDuty, Inspector, Macie, etc. "
|
|
73
|
+
"Alternatively, use the AWS CLI command: "
|
|
74
|
+
f"aws securityhub enable-import-findings-for-product --product-arn [PRODUCT_ARN] --region {region}"
|
|
75
|
+
)
|
|
76
|
+
)
|
|
77
|
+
)
|
|
78
|
+
else:
|
|
79
|
+
# Security Hub is enabled with products
|
|
80
|
+
product_names = []
|
|
81
|
+
for product_arn in enabled_products:
|
|
82
|
+
# Extract the product name from the ARN
|
|
83
|
+
if '/product-subscription/' in product_arn:
|
|
84
|
+
product_name = product_arn.split('/product-subscription/')[1]
|
|
85
|
+
product_names.append(product_name)
|
|
86
|
+
else:
|
|
87
|
+
product_names.append(product_arn)
|
|
88
|
+
|
|
89
|
+
products_list = ', '.join(product_names) if product_names else "None"
|
|
90
|
+
|
|
91
|
+
findings.append(
|
|
92
|
+
self.create_finding(
|
|
93
|
+
status="PASS",
|
|
94
|
+
region=region,
|
|
95
|
+
resource_id=resource_id,
|
|
96
|
+
checked_value="List of products that are enabled in Security Hub",
|
|
97
|
+
actual_value=f"Security Hub has enabled security integrations in region {region}: {products_list}",
|
|
98
|
+
remediation="No remediation needed"
|
|
99
|
+
)
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
return findings
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SRA-SECURITYHUB-06: Security Hub check.
|
|
3
|
+
"""
|
|
4
|
+
from typing import List, Dict, Any
|
|
5
|
+
from sraverify.services.securityhub.base import SecurityHubCheck
|
|
6
|
+
from sraverify.core.logging import logger
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SRA_SECURITYHUB_06(SecurityHubCheck):
|
|
10
|
+
"""Check if Security Hub administration for the AWS Organization has a delegated administrator."""
|
|
11
|
+
|
|
12
|
+
def __init__(self):
|
|
13
|
+
"""Initialize the check."""
|
|
14
|
+
super().__init__()
|
|
15
|
+
self.check_id = "SRA-SECURITYHUB-06"
|
|
16
|
+
self.check_name = "Security Hub administration for the AWS Organization has a delegated administrator"
|
|
17
|
+
self.account_type = "management" # This check is for the management account
|
|
18
|
+
self.severity = "HIGH"
|
|
19
|
+
self.description = (
|
|
20
|
+
"This check verifies whether Security Hub service administration for the AWS Organization "
|
|
21
|
+
"is set to AWS Organization delegated admin account for Security Hub."
|
|
22
|
+
)
|
|
23
|
+
self.check_logic = (
|
|
24
|
+
"Check evaluates securityhub list-organization-admin-accounts and organizations list-delegated-administrators "
|
|
25
|
+
"--service-principal securityhub.amazonaws.com. Check PASS if AccountID and ID returned are the same."
|
|
26
|
+
)
|
|
27
|
+
self.resource_type = "AWS::Organizations::Account"
|
|
28
|
+
|
|
29
|
+
def execute(self) -> List[Dict[str, Any]]:
|
|
30
|
+
"""
|
|
31
|
+
Execute the check.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
List of findings
|
|
35
|
+
"""
|
|
36
|
+
findings = []
|
|
37
|
+
|
|
38
|
+
# This check only needs to run in one region since it's an organization-wide setting
|
|
39
|
+
region = self.regions[0] if self.regions else "us-east-1"
|
|
40
|
+
|
|
41
|
+
# Get organization admin accounts
|
|
42
|
+
admin_accounts = self.get_organization_admin_accounts(region)
|
|
43
|
+
|
|
44
|
+
# Get delegated administrators
|
|
45
|
+
delegated_admins = self.get_delegated_administrators(region)
|
|
46
|
+
|
|
47
|
+
# Check if there's a match between Security Hub admin and Organizations delegated admin
|
|
48
|
+
sh_admin_id = None
|
|
49
|
+
for admin in admin_accounts:
|
|
50
|
+
if admin.get('Status') == 'ENABLED':
|
|
51
|
+
sh_admin_id = admin.get('AccountId')
|
|
52
|
+
break
|
|
53
|
+
|
|
54
|
+
org_admin_id = None
|
|
55
|
+
for admin in delegated_admins:
|
|
56
|
+
org_admin_id = admin.get('Id')
|
|
57
|
+
break
|
|
58
|
+
|
|
59
|
+
resource_id = f"delegated-admin/{self.account_id}"
|
|
60
|
+
|
|
61
|
+
if not sh_admin_id or not org_admin_id:
|
|
62
|
+
findings.append(
|
|
63
|
+
self.create_finding(
|
|
64
|
+
status="FAIL",
|
|
65
|
+
region=region,
|
|
66
|
+
resource_id=resource_id,
|
|
67
|
+
checked_value=(
|
|
68
|
+
"aws organizations list-delegated-administrators --service-principal securityhub.amazonaws.com - "
|
|
69
|
+
"\"DelegatedAdministrators\": \"Id\": \"[ADMIN_ID]\""
|
|
70
|
+
"aws securityhub list-organization-admin-accounts - \"AdminAccounts\": \"AccountId\": \"[ADMIN_ID]\""
|
|
71
|
+
),
|
|
72
|
+
actual_value=f"No Security Hub admin account or Organizations delegated admin found",
|
|
73
|
+
remediation=(
|
|
74
|
+
"Configure a Security Hub delegated administrator account. In the management account, "
|
|
75
|
+
"use the AWS CLI command: "
|
|
76
|
+
f"aws securityhub enable-organization-admin-account --admin-account-id [AUDIT_ACCOUNT_ID] --region {region}"
|
|
77
|
+
)
|
|
78
|
+
)
|
|
79
|
+
)
|
|
80
|
+
elif sh_admin_id != org_admin_id:
|
|
81
|
+
findings.append(
|
|
82
|
+
self.create_finding(
|
|
83
|
+
status="FAIL",
|
|
84
|
+
region=region,
|
|
85
|
+
resource_id=resource_id,
|
|
86
|
+
checked_value=(
|
|
87
|
+
"aws organizations list-delegated-administrators --service-principal securityhub.amazonaws.com - "
|
|
88
|
+
"\"DelegatedAdministrators\": \"Id\": \"[ADMIN_ID]\""
|
|
89
|
+
"aws securityhub list-organization-admin-accounts - \"AdminAccounts\": \"AccountId\": \"[ADMIN_ID]\""
|
|
90
|
+
),
|
|
91
|
+
actual_value=f"Organizations delegated admin for securityhub {org_admin_id} is different than the Security Hub Admin account {sh_admin_id}",
|
|
92
|
+
remediation=(
|
|
93
|
+
"Ensure the same account is used as both the Security Hub admin and the Organizations delegated admin. "
|
|
94
|
+
"First, remove the current delegated admin using: "
|
|
95
|
+
f"aws organizations deregister-delegated-administrator --account-id {org_admin_id} --service-principal securityhub.amazonaws.com"
|
|
96
|
+
"Then, set the Security Hub admin account as the delegated admin: "
|
|
97
|
+
f"aws organizations register-delegated-administrator --account-id {sh_admin_id} --service-principal securityhub.amazonaws.com"
|
|
98
|
+
)
|
|
99
|
+
)
|
|
100
|
+
)
|
|
101
|
+
else:
|
|
102
|
+
findings.append(
|
|
103
|
+
self.create_finding(
|
|
104
|
+
status="PASS",
|
|
105
|
+
region=region,
|
|
106
|
+
resource_id=resource_id,
|
|
107
|
+
checked_value="Security Hub delegated administrator matches organization admin account",
|
|
108
|
+
actual_value=f"Delegated admin account {org_admin_id} matches Security Hub admin account {sh_admin_id}",
|
|
109
|
+
remediation="No remediation needed"
|
|
110
|
+
)
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
return findings
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SRA-SECURITYHUB-07: Security Hub check.
|
|
3
|
+
"""
|
|
4
|
+
from typing import List, Dict, Any
|
|
5
|
+
from sraverify.services.securityhub.base import SecurityHubCheck
|
|
6
|
+
from sraverify.core.logging import logger
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SRA_SECURITYHUB_07(SecurityHubCheck):
|
|
10
|
+
"""Check if Security Hub delegated admin account is the audit account."""
|
|
11
|
+
|
|
12
|
+
def __init__(self):
|
|
13
|
+
"""Initialize the check."""
|
|
14
|
+
super().__init__()
|
|
15
|
+
self.check_id = "SRA-SECURITYHUB-07"
|
|
16
|
+
self.check_name = "Security Hub delegated admin account is the audit account"
|
|
17
|
+
self.account_type = "management" # This check is for the management account
|
|
18
|
+
self.severity = "HIGH"
|
|
19
|
+
self.description = (
|
|
20
|
+
"This check verifies whether Security Hub delegated admin account is the audit account of your AWS organization. "
|
|
21
|
+
"Audit account is dedicated to operating security services, monitoring AWS accounts, and automating security alerting and response. "
|
|
22
|
+
"AWS Security Hub provides a comprehensive view of the security state in AWS and helps assess AWS environment against "
|
|
23
|
+
"security industry standards and best practices."
|
|
24
|
+
)
|
|
25
|
+
self.check_logic = (
|
|
26
|
+
"Check evaluates value from organizations list-delegated-administrators --service-principal securityhub.amazonaws.com "
|
|
27
|
+
"to ensure DelegatedAdministrators ID matches audit account ID passed via flag."
|
|
28
|
+
)
|
|
29
|
+
self._audit_accounts = [] # Will be populated from command line args
|
|
30
|
+
|
|
31
|
+
def execute(self) -> List[Dict[str, Any]]:
|
|
32
|
+
"""
|
|
33
|
+
Execute the check.
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
List of findings
|
|
37
|
+
"""
|
|
38
|
+
findings = []
|
|
39
|
+
|
|
40
|
+
# Check each region separately
|
|
41
|
+
for region in self.regions:
|
|
42
|
+
# Get delegated administrators for Security Hub
|
|
43
|
+
delegated_admins = self.get_delegated_administrators(region)
|
|
44
|
+
|
|
45
|
+
resource_id = f"delegated-admin/{self.account_id}"
|
|
46
|
+
|
|
47
|
+
# If no audit accounts are provided, we can't perform the check
|
|
48
|
+
if not self._audit_accounts:
|
|
49
|
+
findings.append(
|
|
50
|
+
self.create_finding(
|
|
51
|
+
status="ERROR",
|
|
52
|
+
region=region,
|
|
53
|
+
resource_id=resource_id,
|
|
54
|
+
checked_value="Delegated administrator is audit account",
|
|
55
|
+
actual_value="No audit account ID provided for comparison",
|
|
56
|
+
remediation="Provide an audit account ID using the --audit-account flag"
|
|
57
|
+
)
|
|
58
|
+
)
|
|
59
|
+
continue
|
|
60
|
+
|
|
61
|
+
# Use the first audit account in the list
|
|
62
|
+
audit_account_id = self._audit_accounts[0]
|
|
63
|
+
|
|
64
|
+
# Check if there are any delegated administrators
|
|
65
|
+
if not delegated_admins:
|
|
66
|
+
findings.append(
|
|
67
|
+
self.create_finding(
|
|
68
|
+
status="FAIL",
|
|
69
|
+
region=region,
|
|
70
|
+
resource_id=resource_id,
|
|
71
|
+
checked_value=f"Delegated administrator is audit account {audit_account_id}",
|
|
72
|
+
actual_value=f"No Security Hub delegated administrator found in region {region}",
|
|
73
|
+
remediation=(
|
|
74
|
+
f"Register the audit account {audit_account_id} as the Security Hub delegated administrator. "
|
|
75
|
+
f"In the AWS Console, navigate to Security Hub in the management account, go to Settings > General, "
|
|
76
|
+
f"and set the delegated administrator. Alternatively, use the AWS CLI command: "
|
|
77
|
+
f"aws organizations register-delegated-administrator --account-id {audit_account_id} "
|
|
78
|
+
f"--service-principal securityhub.amazonaws.com --region {region}"
|
|
79
|
+
)
|
|
80
|
+
)
|
|
81
|
+
)
|
|
82
|
+
continue
|
|
83
|
+
|
|
84
|
+
# Check if the delegated administrator is the audit account
|
|
85
|
+
delegated_admin_id = None
|
|
86
|
+
for admin in delegated_admins:
|
|
87
|
+
delegated_admin_id = admin.get('Id')
|
|
88
|
+
if delegated_admin_id == audit_account_id:
|
|
89
|
+
findings.append(
|
|
90
|
+
self.create_finding(
|
|
91
|
+
status="PASS",
|
|
92
|
+
region=region,
|
|
93
|
+
resource_id=resource_id,
|
|
94
|
+
checked_value=f"Delegated administrator is audit account {audit_account_id}",
|
|
95
|
+
actual_value=f"Security Hub delegated administrator is the audit account {audit_account_id}",
|
|
96
|
+
remediation="No remediation needed"
|
|
97
|
+
)
|
|
98
|
+
)
|
|
99
|
+
break
|
|
100
|
+
else:
|
|
101
|
+
# If we didn't break out of the loop, the delegated admin is not the audit account
|
|
102
|
+
findings.append(
|
|
103
|
+
self.create_finding(
|
|
104
|
+
status="FAIL",
|
|
105
|
+
region=region,
|
|
106
|
+
resource_id=resource_id,
|
|
107
|
+
checked_value=f"Delegated administrator is audit account {audit_account_id}",
|
|
108
|
+
actual_value=f"Security Hub delegated administrator {delegated_admin_id} is not the audit account {audit_account_id}",
|
|
109
|
+
remediation=(
|
|
110
|
+
f"Update the Security Hub delegated administrator to be the audit account {audit_account_id}. "
|
|
111
|
+
f"First, deregister the current delegated administrator using: "
|
|
112
|
+
f"aws organizations deregister-delegated-administrator --account-id {delegated_admin_id} "
|
|
113
|
+
f"--service-principal securityhub.amazonaws.com --region {region}\n"
|
|
114
|
+
f"Then, register the audit account as the delegated administrator using: "
|
|
115
|
+
f"aws organizations register-delegated-administrator --account-id {audit_account_id} "
|
|
116
|
+
f"--service-principal securityhub.amazonaws.com --region {region}"
|
|
117
|
+
)
|
|
118
|
+
)
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
return findings
|