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.
Files changed (261) hide show
  1. sraverify/__init__.py +36 -0
  2. sraverify/checks/__init__.py +56 -0
  3. sraverify/checks/accessanalyzer/SRA_IAA_1.py +188 -0
  4. sraverify/checks/accessanalyzer/SRA_IAA_2.py +162 -0
  5. sraverify/checks/accessanalyzer/SRA_IAA_3.py +260 -0
  6. sraverify/checks/accessanalyzer/SRA_IAA_4.py +207 -0
  7. sraverify/checks/accessanalyzer/__init__.py +3 -0
  8. sraverify/checks/cloudtrail/SRA-CT-1.py +220 -0
  9. sraverify/checks/cloudtrail/SRA-CT-10.py +229 -0
  10. sraverify/checks/cloudtrail/SRA-CT-11.py +242 -0
  11. sraverify/checks/cloudtrail/SRA-CT-12.py +163 -0
  12. sraverify/checks/cloudtrail/SRA-CT-13.py +279 -0
  13. sraverify/checks/cloudtrail/SRA-CT-2.py +218 -0
  14. sraverify/checks/cloudtrail/SRA-CT-3.py +196 -0
  15. sraverify/checks/cloudtrail/SRA-CT-4.py +161 -0
  16. sraverify/checks/cloudtrail/SRA-CT-5.py +200 -0
  17. sraverify/checks/cloudtrail/SRA-CT-6.py +161 -0
  18. sraverify/checks/cloudtrail/SRA-CT-7.py +194 -0
  19. sraverify/checks/cloudtrail/SRA-CT-8.py +226 -0
  20. sraverify/checks/cloudtrail/SRA-CT-9.py +226 -0
  21. sraverify/checks/cloudtrail/__init__.py +3 -0
  22. sraverify/checks/config/SRA-CONFIG-1.py +197 -0
  23. sraverify/checks/config/__init__.py +3 -0
  24. sraverify/core/__init__.py +3 -0
  25. sraverify/core/check.py +227 -0
  26. sraverify/core/logging.py +37 -0
  27. sraverify/core/session.py +47 -0
  28. sraverify/lib/__init__.py +4 -0
  29. sraverify/lib/audit_info.py +37 -0
  30. sraverify/lib/banner.py +42 -0
  31. sraverify/lib/check_loader.py +80 -0
  32. sraverify/lib/org_mgmt_checker.py +86 -0
  33. sraverify/lib/outputs.py +46 -0
  34. sraverify/lib/progress.py +75 -0
  35. sraverify/lib/regions.py +27 -0
  36. sraverify/lib/session.py +23 -0
  37. sraverify/main.py +350 -0
  38. sraverify/services/__init__.py +3 -0
  39. sraverify/services/accessanalyzer/__init__.py +15 -0
  40. sraverify/services/accessanalyzer/base.py +123 -0
  41. sraverify/services/accessanalyzer/checks/__init__.py +3 -0
  42. sraverify/services/accessanalyzer/checks/sra_accessanalyzer_01.py +82 -0
  43. sraverify/services/accessanalyzer/checks/sra_accessanalyzer_02.py +82 -0
  44. sraverify/services/accessanalyzer/checks/sra_accessanalyzer_03.py +103 -0
  45. sraverify/services/accessanalyzer/checks/sra_accessanalyzer_04.py +139 -0
  46. sraverify/services/accessanalyzer/client.py +123 -0
  47. sraverify/services/account/__init__.py +9 -0
  48. sraverify/services/account/base.py +56 -0
  49. sraverify/services/account/checks/__init__.py +1 -0
  50. sraverify/services/account/checks/sra_account_01.py +65 -0
  51. sraverify/services/account/checks/sra_account_02.py +63 -0
  52. sraverify/services/account/checks/sra_account_03.py +63 -0
  53. sraverify/services/account/client.py +51 -0
  54. sraverify/services/auditmanager/__init__.py +10 -0
  55. sraverify/services/auditmanager/base.py +72 -0
  56. sraverify/services/auditmanager/checks/__init__.py +1 -0
  57. sraverify/services/auditmanager/checks/sra_auditmanager_01.py +58 -0
  58. sraverify/services/auditmanager/checks/sra_auditmanager_02.py +80 -0
  59. sraverify/services/auditmanager/client.py +58 -0
  60. sraverify/services/cloudtrail/__init__.py +33 -0
  61. sraverify/services/cloudtrail/base.py +167 -0
  62. sraverify/services/cloudtrail/checks/__init__.py +1 -0
  63. sraverify/services/cloudtrail/checks/sra_cloudtrail_01.py +83 -0
  64. sraverify/services/cloudtrail/checks/sra_cloudtrail_02.py +99 -0
  65. sraverify/services/cloudtrail/checks/sra_cloudtrail_03.py +94 -0
  66. sraverify/services/cloudtrail/checks/sra_cloudtrail_04.py +92 -0
  67. sraverify/services/cloudtrail/checks/sra_cloudtrail_05.py +106 -0
  68. sraverify/services/cloudtrail/checks/sra_cloudtrail_06.py +93 -0
  69. sraverify/services/cloudtrail/checks/sra_cloudtrail_07.py +96 -0
  70. sraverify/services/cloudtrail/checks/sra_cloudtrail_08.py +145 -0
  71. sraverify/services/cloudtrail/checks/sra_cloudtrail_09.py +167 -0
  72. sraverify/services/cloudtrail/checks/sra_cloudtrail_10.py +162 -0
  73. sraverify/services/cloudtrail/checks/sra_cloudtrail_11.py +178 -0
  74. sraverify/services/cloudtrail/checks/sra_cloudtrail_12.py +77 -0
  75. sraverify/services/cloudtrail/checks/sra_cloudtrail_13.py +120 -0
  76. sraverify/services/cloudtrail/client.py +118 -0
  77. sraverify/services/config/__init__.py +25 -0
  78. sraverify/services/config/base.py +249 -0
  79. sraverify/services/config/checks/__init__.py +1 -0
  80. sraverify/services/config/checks/sra_config_01.py +123 -0
  81. sraverify/services/config/checks/sra_config_02.py +156 -0
  82. sraverify/services/config/checks/sra_config_03.py +149 -0
  83. sraverify/services/config/checks/sra_config_04.py +104 -0
  84. sraverify/services/config/checks/sra_config_05.py +104 -0
  85. sraverify/services/config/checks/sra_config_06.py +194 -0
  86. sraverify/services/config/checks/sra_config_07.py +162 -0
  87. sraverify/services/config/checks/sra_config_08.py +185 -0
  88. sraverify/services/config/checks/sra_config_09.py +177 -0
  89. sraverify/services/config/client.py +264 -0
  90. sraverify/services/ec2/__init__.py +8 -0
  91. sraverify/services/ec2/base.py +75 -0
  92. sraverify/services/ec2/checks/__init__.py +1 -0
  93. sraverify/services/ec2/checks/sra_ec2_01.py +83 -0
  94. sraverify/services/ec2/client.py +63 -0
  95. sraverify/services/firewallmanager/__init__.py +23 -0
  96. sraverify/services/firewallmanager/base.py +48 -0
  97. sraverify/services/firewallmanager/checks/__init__.py +1 -0
  98. sraverify/services/firewallmanager/checks/sra_firewallmanager_01.py +75 -0
  99. sraverify/services/firewallmanager/checks/sra_firewallmanager_02.py +57 -0
  100. sraverify/services/firewallmanager/checks/sra_firewallmanager_03.py +51 -0
  101. sraverify/services/firewallmanager/checks/sra_firewallmanager_04.py +51 -0
  102. sraverify/services/firewallmanager/checks/sra_firewallmanager_05.py +51 -0
  103. sraverify/services/firewallmanager/checks/sra_firewallmanager_06.py +51 -0
  104. sraverify/services/firewallmanager/checks/sra_firewallmanager_07.py +51 -0
  105. sraverify/services/firewallmanager/checks/sra_firewallmanager_08.py +61 -0
  106. sraverify/services/firewallmanager/checks/sra_firewallmanager_09.py +61 -0
  107. sraverify/services/firewallmanager/checks/sra_firewallmanager_10.py +71 -0
  108. sraverify/services/firewallmanager/client.py +40 -0
  109. sraverify/services/guardduty/__init__.py +58 -0
  110. sraverify/services/guardduty/base.py +207 -0
  111. sraverify/services/guardduty/checks/__init__.py +3 -0
  112. sraverify/services/guardduty/checks/sra_guardduty_01.py +51 -0
  113. sraverify/services/guardduty/checks/sra_guardduty_02.py +80 -0
  114. sraverify/services/guardduty/checks/sra_guardduty_03.py +77 -0
  115. sraverify/services/guardduty/checks/sra_guardduty_04.py +84 -0
  116. sraverify/services/guardduty/checks/sra_guardduty_05.py +84 -0
  117. sraverify/services/guardduty/checks/sra_guardduty_06.py +84 -0
  118. sraverify/services/guardduty/checks/sra_guardduty_07.py +85 -0
  119. sraverify/services/guardduty/checks/sra_guardduty_08.py +83 -0
  120. sraverify/services/guardduty/checks/sra_guardduty_09.py +84 -0
  121. sraverify/services/guardduty/checks/sra_guardduty_10.py +83 -0
  122. sraverify/services/guardduty/checks/sra_guardduty_11.py +93 -0
  123. sraverify/services/guardduty/checks/sra_guardduty_12.py +83 -0
  124. sraverify/services/guardduty/checks/sra_guardduty_13.py +90 -0
  125. sraverify/services/guardduty/checks/sra_guardduty_14.py +136 -0
  126. sraverify/services/guardduty/checks/sra_guardduty_15.py +94 -0
  127. sraverify/services/guardduty/checks/sra_guardduty_16.py +94 -0
  128. sraverify/services/guardduty/checks/sra_guardduty_17.py +91 -0
  129. sraverify/services/guardduty/checks/sra_guardduty_18.py +91 -0
  130. sraverify/services/guardduty/checks/sra_guardduty_19.py +91 -0
  131. sraverify/services/guardduty/checks/sra_guardduty_20.py +111 -0
  132. sraverify/services/guardduty/checks/sra_guardduty_21.py +112 -0
  133. sraverify/services/guardduty/checks/sra_guardduty_22.py +111 -0
  134. sraverify/services/guardduty/checks/sra_guardduty_23.py +154 -0
  135. sraverify/services/guardduty/checks/sra_guardduty_24.py +111 -0
  136. sraverify/services/guardduty/checks/sra_guardduty_25.py +111 -0
  137. sraverify/services/guardduty/client.py +107 -0
  138. sraverify/services/inspector/__init__.py +29 -0
  139. sraverify/services/inspector/base.py +233 -0
  140. sraverify/services/inspector/checks/__init__.py +3 -0
  141. sraverify/services/inspector/checks/sra_inspector_01.py +69 -0
  142. sraverify/services/inspector/checks/sra_inspector_02.py +68 -0
  143. sraverify/services/inspector/checks/sra_inspector_03.py +68 -0
  144. sraverify/services/inspector/checks/sra_inspector_04.py +70 -0
  145. sraverify/services/inspector/checks/sra_inspector_05.py +69 -0
  146. sraverify/services/inspector/checks/sra_inspector_06.py +115 -0
  147. sraverify/services/inspector/checks/sra_inspector_07.py +109 -0
  148. sraverify/services/inspector/checks/sra_inspector_08.py +69 -0
  149. sraverify/services/inspector/checks/sra_inspector_09.py +69 -0
  150. sraverify/services/inspector/checks/sra_inspector_10.py +69 -0
  151. sraverify/services/inspector/checks/sra_inspector_11.py +69 -0
  152. sraverify/services/inspector/client.py +99 -0
  153. sraverify/services/macie/__init__.py +27 -0
  154. sraverify/services/macie/base.py +271 -0
  155. sraverify/services/macie/checks/__init__.py +1 -0
  156. sraverify/services/macie/checks/sra_macie_01.py +100 -0
  157. sraverify/services/macie/checks/sra_macie_02.py +102 -0
  158. sraverify/services/macie/checks/sra_macie_03.py +152 -0
  159. sraverify/services/macie/checks/sra_macie_04.py +120 -0
  160. sraverify/services/macie/checks/sra_macie_05.py +85 -0
  161. sraverify/services/macie/checks/sra_macie_06.py +124 -0
  162. sraverify/services/macie/checks/sra_macie_07.py +138 -0
  163. sraverify/services/macie/checks/sra_macie_08.py +82 -0
  164. sraverify/services/macie/checks/sra_macie_09.py +103 -0
  165. sraverify/services/macie/checks/sra_macie_10.py +81 -0
  166. sraverify/services/macie/client.py +220 -0
  167. sraverify/services/s3/__init__.py +16 -0
  168. sraverify/services/s3/base.py +69 -0
  169. sraverify/services/s3/checks/__init__.py +1 -0
  170. sraverify/services/s3/checks/sra_s3_01.py +89 -0
  171. sraverify/services/s3/checks/sra_s3_02.py +89 -0
  172. sraverify/services/s3/checks/sra_s3_03.py +88 -0
  173. sraverify/services/s3/checks/sra_s3_04.py +88 -0
  174. sraverify/services/s3/client.py +52 -0
  175. sraverify/services/securityhub/__init__.py +27 -0
  176. sraverify/services/securityhub/base.py +349 -0
  177. sraverify/services/securityhub/checks/__init__.py +1 -0
  178. sraverify/services/securityhub/checks/sra_securityhub_01.py +115 -0
  179. sraverify/services/securityhub/checks/sra_securityhub_02.py +114 -0
  180. sraverify/services/securityhub/checks/sra_securityhub_03.py +136 -0
  181. sraverify/services/securityhub/checks/sra_securityhub_04.py +75 -0
  182. sraverify/services/securityhub/checks/sra_securityhub_05.py +102 -0
  183. sraverify/services/securityhub/checks/sra_securityhub_06.py +113 -0
  184. sraverify/services/securityhub/checks/sra_securityhub_07.py +121 -0
  185. sraverify/services/securityhub/checks/sra_securityhub_08.py +113 -0
  186. sraverify/services/securityhub/checks/sra_securityhub_09.py +100 -0
  187. sraverify/services/securityhub/checks/sra_securityhub_10.py +94 -0
  188. sraverify/services/securityhub/checks/sra_securityhub_11.py +73 -0
  189. sraverify/services/securityhub/client.py +249 -0
  190. sraverify/services/securityincidentresponse/__init__.py +13 -0
  191. sraverify/services/securityincidentresponse/base.py +95 -0
  192. sraverify/services/securityincidentresponse/checks/__init__.py +1 -0
  193. sraverify/services/securityincidentresponse/checks/sra_securityincidentresponse_01.py +77 -0
  194. sraverify/services/securityincidentresponse/checks/sra_securityincidentresponse_02.py +72 -0
  195. sraverify/services/securityincidentresponse/checks/sra_securityincidentresponse_03.py +86 -0
  196. sraverify/services/securityincidentresponse/checks/sra_securityincidentresponse_04.py +117 -0
  197. sraverify/services/securityincidentresponse/checks/sra_securityincidentresponse_05.py +55 -0
  198. sraverify/services/securityincidentresponse/client.py +71 -0
  199. sraverify/services/securitylake/__init__.py +39 -0
  200. sraverify/services/securitylake/base.py +461 -0
  201. sraverify/services/securitylake/checks/__init__.py +1 -0
  202. sraverify/services/securitylake/checks/sra_securitylake_01.py +98 -0
  203. sraverify/services/securitylake/checks/sra_securitylake_02.py +133 -0
  204. sraverify/services/securitylake/checks/sra_securitylake_03.py +116 -0
  205. sraverify/services/securitylake/checks/sra_securitylake_04.py +72 -0
  206. sraverify/services/securitylake/checks/sra_securitylake_05.py +116 -0
  207. sraverify/services/securitylake/checks/sra_securitylake_06.py +104 -0
  208. sraverify/services/securitylake/checks/sra_securitylake_07.py +108 -0
  209. sraverify/services/securitylake/checks/sra_securitylake_08.py +107 -0
  210. sraverify/services/securitylake/checks/sra_securitylake_09.py +107 -0
  211. sraverify/services/securitylake/checks/sra_securitylake_10.py +106 -0
  212. sraverify/services/securitylake/checks/sra_securitylake_11.py +109 -0
  213. sraverify/services/securitylake/checks/sra_securitylake_12.py +108 -0
  214. sraverify/services/securitylake/checks/sra_securitylake_13.py +108 -0
  215. sraverify/services/securitylake/checks/sra_securitylake_14.py +72 -0
  216. sraverify/services/securitylake/checks/sra_securitylake_15.py +120 -0
  217. sraverify/services/securitylake/checks/sra_securitylake_16.py +104 -0
  218. sraverify/services/securitylake/checks/sra_securitylake_17.py +103 -0
  219. sraverify/services/securitylake/client.py +247 -0
  220. sraverify/services/shield/__init__.py +33 -0
  221. sraverify/services/shield/base.py +199 -0
  222. sraverify/services/shield/checks/__init__.py +1 -0
  223. sraverify/services/shield/checks/sra_shield_01.py +68 -0
  224. sraverify/services/shield/checks/sra_shield_02.py +77 -0
  225. sraverify/services/shield/checks/sra_shield_03.py +84 -0
  226. sraverify/services/shield/checks/sra_shield_04.py +84 -0
  227. sraverify/services/shield/checks/sra_shield_05.py +84 -0
  228. sraverify/services/shield/checks/sra_shield_06.py +84 -0
  229. sraverify/services/shield/checks/sra_shield_07.py +84 -0
  230. sraverify/services/shield/checks/sra_shield_08.py +69 -0
  231. sraverify/services/shield/checks/sra_shield_09.py +86 -0
  232. sraverify/services/shield/checks/sra_shield_10.py +100 -0
  233. sraverify/services/shield/checks/sra_shield_11.py +71 -0
  234. sraverify/services/shield/checks/sra_shield_12.py +130 -0
  235. sraverify/services/shield/checks/sra_shield_13.py +112 -0
  236. sraverify/services/shield/checks/sra_shield_14.py +111 -0
  237. sraverify/services/shield/client.py +214 -0
  238. sraverify/services/waf/__init__.py +21 -0
  239. sraverify/services/waf/base.py +100 -0
  240. sraverify/services/waf/checks/__init__.py +1 -0
  241. sraverify/services/waf/checks/sra_waf_01.py +63 -0
  242. sraverify/services/waf/checks/sra_waf_02.py +82 -0
  243. sraverify/services/waf/checks/sra_waf_03.py +123 -0
  244. sraverify/services/waf/checks/sra_waf_04.py +94 -0
  245. sraverify/services/waf/checks/sra_waf_05.py +94 -0
  246. sraverify/services/waf/checks/sra_waf_06.py +91 -0
  247. sraverify/services/waf/checks/sra_waf_07.py +94 -0
  248. sraverify/services/waf/checks/sra_waf_08.py +66 -0
  249. sraverify/services/waf/checks/sra_waf_09.py +95 -0
  250. sraverify/services/waf/client.py +109 -0
  251. sraverify/utils/__init__.py +3 -0
  252. sraverify/utils/banner.py +65 -0
  253. sraverify/utils/outputs.py +57 -0
  254. sraverify/utils/progress.py +97 -0
  255. sraverify-0.1.0.dist-info/LICENSE +175 -0
  256. sraverify-0.1.0.dist-info/METADATA +516 -0
  257. sraverify-0.1.0.dist-info/NOTICE +1 -0
  258. sraverify-0.1.0.dist-info/RECORD +261 -0
  259. sraverify-0.1.0.dist-info/WHEEL +5 -0
  260. sraverify-0.1.0.dist-info/entry_points.txt +2 -0
  261. sraverify-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,84 @@
1
+ """
2
+ Check if Shield Advanced is configured for Route 53 hosted zones.
3
+ """
4
+ from typing import Dict, List, Any
5
+ from sraverify.services.shield.base import ShieldCheck
6
+
7
+
8
+ class SRA_SHIELD_06(ShieldCheck):
9
+ """Check if Shield Advanced is configured for Route 53 hosted zones."""
10
+
11
+ def __init__(self):
12
+ """Initialize Shield Advanced Route 53 protection check."""
13
+ super().__init__()
14
+ self.check_id = "SRA-SHIELD-06"
15
+ self.check_name = "Shield Advanced is configured for Route 53 hosted zones"
16
+ self.description = ("This check verifies that AWS Shield Advanced is protecting "
17
+ "at least one Route 53 hosted zone.")
18
+ self.severity = "HIGH"
19
+ self.check_logic = ("List Shield protections and filter by Route 53 ARNs. "
20
+ "Check fails if no Route 53 hosted zones are protected.")
21
+
22
+ def execute(self) -> List[Dict[str, Any]]:
23
+ """
24
+ Execute the check.
25
+
26
+ Returns:
27
+ List of findings
28
+ """
29
+ # Shield is a global service, check only in us-east-1
30
+ region = "us-east-1"
31
+ protections = self.list_protections(region)
32
+
33
+ if "Error" in protections:
34
+ error_code = protections["Error"].get("Code", "")
35
+ if error_code == "ResourceNotFoundException":
36
+ self.findings.append(self.create_finding(
37
+ status="FAIL",
38
+ region=region,
39
+ resource_id=None,
40
+ actual_value="Shield Advanced subscription not found",
41
+ remediation="Enable Shield Advanced subscription to protect resources"
42
+ ))
43
+ else:
44
+ self.findings.append(self.create_finding(
45
+ status="ERROR",
46
+ region=region,
47
+ resource_id=None,
48
+ actual_value=protections["Error"].get("Message", "Unknown error"),
49
+ remediation="Check IAM permissions for Shield API access"
50
+ ))
51
+ elif protections.get("Protections"):
52
+ # Filter for Route 53 hosted zones by checking ResourceArn
53
+ route53_protections = [
54
+ p for p in protections["Protections"]
55
+ if "route53" in p.get("ResourceArn", "").lower() and "hostedzone" in p.get("ResourceArn", "").lower()
56
+ ]
57
+
58
+ if route53_protections:
59
+ protected_count = len(route53_protections)
60
+ self.findings.append(self.create_finding(
61
+ status="PASS",
62
+ region=region,
63
+ resource_id="shield:route53-protections",
64
+ actual_value=f"{protected_count} Route 53 hosted zone(s) protected",
65
+ remediation=""
66
+ ))
67
+ else:
68
+ self.findings.append(self.create_finding(
69
+ status="FAIL",
70
+ region=region,
71
+ resource_id=None,
72
+ actual_value="No Route 53 hosted zones protected",
73
+ remediation="Enable Shield Advanced protection for Route 53 hosted zones in the AWS Shield console"
74
+ ))
75
+ else:
76
+ self.findings.append(self.create_finding(
77
+ status="FAIL",
78
+ region=region,
79
+ resource_id=None,
80
+ actual_value="No Route 53 hosted zones protected",
81
+ remediation="Enable Shield Advanced protection for Route 53 hosted zones in the AWS Shield console"
82
+ ))
83
+
84
+ return self.findings
@@ -0,0 +1,84 @@
1
+ """
2
+ Check if Shield Advanced is configured for Global Accelerator.
3
+ """
4
+ from typing import Dict, List, Any
5
+ from sraverify.services.shield.base import ShieldCheck
6
+
7
+
8
+ class SRA_SHIELD_07(ShieldCheck):
9
+ """Check if Shield Advanced is configured for Global Accelerator."""
10
+
11
+ def __init__(self):
12
+ """Initialize Shield Advanced Global Accelerator protection check."""
13
+ super().__init__()
14
+ self.check_id = "SRA-SHIELD-07"
15
+ self.check_name = "Shield Advanced is configured for Global Accelerator"
16
+ self.description = ("This check verifies that AWS Shield Advanced is protecting "
17
+ "at least one Global Accelerator accelerator.")
18
+ self.severity = "HIGH"
19
+ self.check_logic = ("List Shield protections and filter by Global Accelerator ARNs. "
20
+ "Check fails if no Global Accelerator accelerators are protected.")
21
+
22
+ def execute(self) -> List[Dict[str, Any]]:
23
+ """
24
+ Execute the check.
25
+
26
+ Returns:
27
+ List of findings
28
+ """
29
+ # Shield is a global service, check only in us-east-1
30
+ region = "us-east-1"
31
+ protections = self.list_protections(region)
32
+
33
+ if "Error" in protections:
34
+ error_code = protections["Error"].get("Code", "")
35
+ if error_code == "ResourceNotFoundException":
36
+ self.findings.append(self.create_finding(
37
+ status="FAIL",
38
+ region=region,
39
+ resource_id=None,
40
+ actual_value="Shield Advanced subscription not found",
41
+ remediation="Enable Shield Advanced subscription to protect resources"
42
+ ))
43
+ else:
44
+ self.findings.append(self.create_finding(
45
+ status="ERROR",
46
+ region=region,
47
+ resource_id=None,
48
+ actual_value=protections["Error"].get("Message", "Unknown error"),
49
+ remediation="Check IAM permissions for Shield API access"
50
+ ))
51
+ elif protections.get("Protections"):
52
+ # Filter for Global Accelerator by checking ResourceArn
53
+ ga_protections = [
54
+ p for p in protections["Protections"]
55
+ if "globalaccelerator" in p.get("ResourceArn", "").lower()
56
+ ]
57
+
58
+ if ga_protections:
59
+ protected_count = len(ga_protections)
60
+ self.findings.append(self.create_finding(
61
+ status="PASS",
62
+ region=region,
63
+ resource_id="shield:globalaccelerator-protections",
64
+ actual_value=f"{protected_count} Global Accelerator accelerator(s) protected",
65
+ remediation=""
66
+ ))
67
+ else:
68
+ self.findings.append(self.create_finding(
69
+ status="FAIL",
70
+ region=region,
71
+ resource_id=None,
72
+ actual_value="No Global Accelerator accelerators protected",
73
+ remediation="Enable Shield Advanced protection for Global Accelerator accelerators in the AWS Shield console"
74
+ ))
75
+ else:
76
+ self.findings.append(self.create_finding(
77
+ status="FAIL",
78
+ region=region,
79
+ resource_id=None,
80
+ actual_value="No Global Accelerator accelerators protected",
81
+ remediation="Enable Shield Advanced protection for Global Accelerator accelerators in the AWS Shield console"
82
+ ))
83
+
84
+ return self.findings
@@ -0,0 +1,69 @@
1
+ """
2
+ Check if Shield Response Team (SRT) access is configured.
3
+ """
4
+ from typing import Dict, List, Any
5
+ from sraverify.services.shield.base import ShieldCheck
6
+
7
+
8
+ class SRA_SHIELD_08(ShieldCheck):
9
+ """Check if Shield Response Team (SRT) access is configured."""
10
+
11
+ def __init__(self):
12
+ """Initialize Shield Response Team access check."""
13
+ super().__init__()
14
+ self.check_id = "SRA-SHIELD-08"
15
+ self.check_name = "Shield Response Team (SRT) access is configured"
16
+ self.description = ("This check verifies that AWS Shield Response Team (SRT) "
17
+ "access is configured with an appropriate IAM role.")
18
+ self.severity = "MEDIUM"
19
+ self.check_logic = "Describe DRT access configuration. Check fails if no role ARN is configured."
20
+
21
+ def execute(self) -> List[Dict[str, Any]]:
22
+ """
23
+ Execute the check.
24
+
25
+ Returns:
26
+ List of findings
27
+ """
28
+ # Shield is a global service, check only in us-east-1
29
+ region = "us-east-1"
30
+ drt_access = self.describe_drt_access(region)
31
+
32
+ if "Error" in drt_access:
33
+ error_code = drt_access["Error"].get("Code", "")
34
+ if error_code == "ResourceNotFoundException":
35
+ self.findings.append(self.create_finding(
36
+ status="FAIL",
37
+ region=region,
38
+ resource_id=None,
39
+ actual_value="SRT access not configured",
40
+ remediation="Configure Shield Response Team access by associating an IAM role using AssociateDRTRole API"
41
+ ))
42
+ else:
43
+ self.findings.append(self.create_finding(
44
+ status="ERROR",
45
+ region=region,
46
+ resource_id=None,
47
+ actual_value=drt_access["Error"].get("Message", "Unknown error"),
48
+ remediation="Check IAM permissions for Shield API access"
49
+ ))
50
+ elif drt_access.get("RoleArn"):
51
+ role_arn = drt_access["RoleArn"]
52
+ bucket_count = len(drt_access.get("LogBucketList", []))
53
+ self.findings.append(self.create_finding(
54
+ status="PASS",
55
+ region=region,
56
+ resource_id="shield:srt-access",
57
+ actual_value=f"SRT access configured with role: {role_arn}, {bucket_count} log bucket(s)",
58
+ remediation=""
59
+ ))
60
+ else:
61
+ self.findings.append(self.create_finding(
62
+ status="FAIL",
63
+ region=region,
64
+ resource_id=None,
65
+ actual_value="SRT access not configured",
66
+ remediation="Configure Shield Response Team access by associating an IAM role using AssociateDRTRole API"
67
+ ))
68
+
69
+ return self.findings
@@ -0,0 +1,86 @@
1
+ """
2
+ Check if Shield Advanced proactive engagement is enabled.
3
+ """
4
+ from typing import Dict, List, Any
5
+ from sraverify.services.shield.base import ShieldCheck
6
+
7
+
8
+ class SRA_SHIELD_09(ShieldCheck):
9
+ """Check if Shield Advanced proactive engagement is enabled."""
10
+
11
+ def __init__(self):
12
+ """Initialize Shield Advanced proactive engagement check."""
13
+ super().__init__()
14
+ self.check_id = "SRA-SHIELD-09"
15
+ self.check_name = "Shield Advanced proactive engagement is enabled"
16
+ self.description = ("This check verifies that AWS Shield Advanced proactive engagement "
17
+ "is enabled, allowing the Shield Response Team to contact you directly during attacks.")
18
+ self.severity = "MEDIUM"
19
+ self.check_logic = ("Get Shield subscription details and check ProactiveEngagementStatus. "
20
+ "Check fails if proactive engagement is disabled.")
21
+
22
+ def execute(self) -> List[Dict[str, Any]]:
23
+ """
24
+ Execute the check.
25
+
26
+ Returns:
27
+ List of findings
28
+ """
29
+ # Shield is a global service, check only in us-east-1
30
+ region = "us-east-1"
31
+ subscription = self.get_subscription_state(region)
32
+
33
+ if "Error" in subscription:
34
+ error_code = subscription["Error"].get("Code", "")
35
+ if error_code == "ResourceNotFoundException":
36
+ self.findings.append(self.create_finding(
37
+ status="FAIL",
38
+ region=region,
39
+ resource_id=None,
40
+ actual_value="Shield Advanced not subscribed",
41
+ remediation="Enable Shield Advanced subscription in the AWS Shield console"
42
+ ))
43
+ else:
44
+ self.findings.append(self.create_finding(
45
+ status="ERROR",
46
+ region=region,
47
+ resource_id=None,
48
+ actual_value=subscription["Error"].get("Message", "Unknown error"),
49
+ remediation="Check IAM permissions for Shield API access"
50
+ ))
51
+ elif "Subscription" in subscription:
52
+ proactive_status = subscription["Subscription"].get("ProactiveEngagementStatus", "")
53
+ if proactive_status == "ENABLED":
54
+ self.findings.append(self.create_finding(
55
+ status="PASS",
56
+ region=region,
57
+ resource_id="shield:proactive-engagement",
58
+ actual_value="Proactive engagement is enabled",
59
+ remediation=""
60
+ ))
61
+ elif proactive_status == "PENDING":
62
+ self.findings.append(self.create_finding(
63
+ status="FAIL",
64
+ region=region,
65
+ resource_id="shield:proactive-engagement",
66
+ actual_value="Proactive engagement is pending",
67
+ remediation="Complete proactive engagement setup by providing emergency contacts"
68
+ ))
69
+ else:
70
+ self.findings.append(self.create_finding(
71
+ status="FAIL",
72
+ region=region,
73
+ resource_id="shield:proactive-engagement",
74
+ actual_value=f"Proactive engagement is {proactive_status or 'disabled'}",
75
+ remediation="Enable proactive engagement using EnableProactiveEngagement API and configure emergency contacts"
76
+ ))
77
+ else:
78
+ self.findings.append(self.create_finding(
79
+ status="FAIL",
80
+ region=region,
81
+ resource_id=None,
82
+ actual_value="Shield Advanced subscription not found",
83
+ remediation="Enable Shield Advanced subscription in the AWS Shield console"
84
+ ))
85
+
86
+ return self.findings
@@ -0,0 +1,100 @@
1
+ """
2
+ Check if health checks are configured for Shield Advanced protected resources.
3
+ """
4
+ from typing import Dict, List, Any
5
+ from sraverify.services.shield.base import ShieldCheck
6
+
7
+
8
+ class SRA_SHIELD_10(ShieldCheck):
9
+ """Check if health checks are configured for Shield Advanced protected resources."""
10
+
11
+ def __init__(self):
12
+ """Initialize Shield Advanced health checks check."""
13
+ super().__init__()
14
+ self.check_id = "SRA-SHIELD-10"
15
+ self.check_name = "Health checks are configured for Shield Advanced protected resources"
16
+ self.description = ("This check verifies that Route 53 health checks are associated "
17
+ "with Shield Advanced protected resources to enable health-based detection. "
18
+ "Route 53 hosted zones are excluded as they don't support health-based detection.")
19
+ self.severity = "MEDIUM"
20
+ self.check_logic = ("List Shield protections and check HealthCheckIds field. "
21
+ "Check fails if protected resources (excluding Route 53 hosted zones) lack health checks.")
22
+
23
+ def execute(self) -> List[Dict[str, Any]]:
24
+ """
25
+ Execute the check.
26
+
27
+ Returns:
28
+ List of findings
29
+ """
30
+ # Shield is a global service, check only in us-east-1
31
+ region = "us-east-1"
32
+ protections = self.list_protections(region)
33
+
34
+ if "Error" in protections:
35
+ error_code = protections["Error"].get("Code", "")
36
+ if error_code == "ResourceNotFoundException":
37
+ self.findings.append(self.create_finding(
38
+ status="FAIL",
39
+ region=region,
40
+ resource_id=None,
41
+ actual_value="Shield Advanced subscription not found",
42
+ remediation="Enable Shield Advanced subscription to protect resources"
43
+ ))
44
+ else:
45
+ self.findings.append(self.create_finding(
46
+ status="ERROR",
47
+ region=region,
48
+ resource_id=None,
49
+ actual_value=protections["Error"].get("Message", "Unknown error"),
50
+ remediation="Check IAM permissions for Shield API access"
51
+ ))
52
+ elif protections.get("Protections"):
53
+ # Filter out Route 53 hosted zones as they don't support health-based detection
54
+ eligible_protections = [
55
+ p for p in protections["Protections"]
56
+ if not ("route53" in p.get("ResourceArn", "").lower() and "hostedzone" in p.get("ResourceArn", "").lower())
57
+ ]
58
+
59
+ if not eligible_protections:
60
+ self.findings.append(self.create_finding(
61
+ status="PASS",
62
+ region=region,
63
+ resource_id="shield:health-checks",
64
+ actual_value="No resources requiring health checks found (only Route 53 hosted zones protected)",
65
+ remediation=""
66
+ ))
67
+ return self.findings
68
+
69
+ # Create a finding for each eligible protected resource
70
+ for protection in eligible_protections:
71
+ resource_arn = protection.get("ResourceArn", "")
72
+ protection_name = protection.get("Name", "Unknown")
73
+ health_check_ids = protection.get("HealthCheckIds", [])
74
+
75
+ if health_check_ids:
76
+ self.findings.append(self.create_finding(
77
+ status="PASS",
78
+ region=region,
79
+ resource_id=resource_arn,
80
+ actual_value=f"Health check configured: {len(health_check_ids)} health check(s)",
81
+ remediation=""
82
+ ))
83
+ else:
84
+ self.findings.append(self.create_finding(
85
+ status="FAIL",
86
+ region=region,
87
+ resource_id=resource_arn,
88
+ actual_value="No health check configured",
89
+ remediation="Associate a Route 53 health check with this Shield Advanced protected resource"
90
+ ))
91
+ else:
92
+ self.findings.append(self.create_finding(
93
+ status="FAIL",
94
+ region=region,
95
+ resource_id=None,
96
+ actual_value="No Shield Advanced protections found",
97
+ remediation="Enable Shield Advanced protection for resources and configure health checks"
98
+ ))
99
+
100
+ return self.findings
@@ -0,0 +1,71 @@
1
+ """
2
+ Check if Shield engagement Lambda function is configured.
3
+ """
4
+ from typing import Dict, List, Any
5
+ from sraverify.services.shield.base import ShieldCheck
6
+
7
+
8
+ class SRA_SHIELD_11(ShieldCheck):
9
+ """Check if Shield engagement Lambda function is configured."""
10
+
11
+ def __init__(self):
12
+ """Initialize Shield engagement Lambda function check."""
13
+ super().__init__()
14
+ self.check_id = "SRA-SHIELD-11"
15
+ self.check_name = "Shield engagement Lambda function is configured"
16
+ self.description = ("This check verifies that a Lambda function named "
17
+ "'AWS_Shield_Engagement_Lambda' exists to automate support case creation during DDoS events.")
18
+ self.severity = "MEDIUM"
19
+ self.check_logic = "Check for existence of Lambda function named 'AWS_Shield_Engagement_Lambda' in us-east-1."
20
+
21
+ def execute(self) -> List[Dict[str, Any]]:
22
+ """
23
+ Execute the check.
24
+
25
+ Returns:
26
+ List of findings
27
+ """
28
+ # Check for Lambda function in us-east-1
29
+ region = "us-east-1"
30
+ function_name = "AWS_Shield_Engagement_Lambda"
31
+
32
+ lambda_function = self.get_lambda_function(region, function_name)
33
+
34
+ if "Error" in lambda_function:
35
+ error_code = lambda_function["Error"].get("Code", "")
36
+ if error_code == "ResourceNotFoundException":
37
+ self.findings.append(self.create_finding(
38
+ status="FAIL",
39
+ region=region,
40
+ resource_id=None,
41
+ actual_value="Shield engagement Lambda function not found",
42
+ remediation=f"Create Lambda function named '{function_name}' to automate support case creation during DDoS events"
43
+ ))
44
+ else:
45
+ self.findings.append(self.create_finding(
46
+ status="ERROR",
47
+ region=region,
48
+ resource_id=None,
49
+ actual_value=lambda_function["Error"].get("Message", "Unknown error"),
50
+ remediation="Check IAM permissions for Lambda API access"
51
+ ))
52
+ elif lambda_function.get("Configuration"):
53
+ function_arn = lambda_function["Configuration"].get("FunctionArn", "")
54
+ runtime = lambda_function["Configuration"].get("Runtime", "")
55
+ self.findings.append(self.create_finding(
56
+ status="PASS",
57
+ region=region,
58
+ resource_id=function_arn,
59
+ actual_value=f"Shield engagement Lambda function exists (Runtime: {runtime})",
60
+ remediation=""
61
+ ))
62
+ else:
63
+ self.findings.append(self.create_finding(
64
+ status="FAIL",
65
+ region=region,
66
+ resource_id=None,
67
+ actual_value="Shield engagement Lambda function not found",
68
+ remediation=f"Create Lambda function named '{function_name}' to automate support case creation during DDoS events"
69
+ ))
70
+
71
+ return self.findings
@@ -0,0 +1,130 @@
1
+ """
2
+ Check if Shield Advanced protected resources have WAF web ACLs associated.
3
+ """
4
+ from typing import Dict, List, Any
5
+ from sraverify.services.shield.base import ShieldCheck
6
+
7
+
8
+ class SRA_SHIELD_12(ShieldCheck):
9
+ """Check if Shield Advanced protected resources have WAF web ACLs associated."""
10
+
11
+ def __init__(self):
12
+ """Initialize Shield Advanced WAF association check."""
13
+ super().__init__()
14
+ self.check_id = "SRA-SHIELD-12"
15
+ self.check_name = "Shield Advanced protected resources have WAF web ACLs associated"
16
+ self.description = ("This check verifies that Shield Advanced protected resources "
17
+ "that support WAF (CloudFront distributions and Application Load Balancers) "
18
+ "have web ACLs associated for enhanced application layer protection.")
19
+ self.severity = "HIGH"
20
+ self.check_logic = ("List Shield protections and check WAF web ACL associations "
21
+ "for CloudFront distributions and Application Load Balancers.")
22
+
23
+ def execute(self) -> List[Dict[str, Any]]:
24
+ """
25
+ Execute the check.
26
+
27
+ Returns:
28
+ List of findings
29
+ """
30
+ # Shield is a global service, check only in us-east-1
31
+ region = "us-east-1"
32
+ protections = self.list_protections(region)
33
+
34
+ if "Error" in protections:
35
+ error_code = protections["Error"].get("Code", "")
36
+ if error_code == "ResourceNotFoundException":
37
+ self.findings.append(self.create_finding(
38
+ status="FAIL",
39
+ region=region,
40
+ resource_id=None,
41
+ actual_value="Shield Advanced subscription not found",
42
+ remediation="Enable Shield Advanced subscription to protect resources"
43
+ ))
44
+ else:
45
+ self.findings.append(self.create_finding(
46
+ status="ERROR",
47
+ region=region,
48
+ resource_id=None,
49
+ actual_value=protections["Error"].get("Message", "Unknown error"),
50
+ remediation="Check IAM permissions for Shield API access"
51
+ ))
52
+ elif protections.get("Protections"):
53
+ # Filter for resources that support WAF (CloudFront and ALB)
54
+ waf_eligible_protections = [
55
+ p for p in protections["Protections"]
56
+ if ("cloudfront" in p.get("ResourceArn", "").lower() or
57
+ "elasticloadbalancing" in p.get("ResourceArn", "").lower())
58
+ ]
59
+
60
+ if not waf_eligible_protections:
61
+ self.findings.append(self.create_finding(
62
+ status="PASS",
63
+ region=region,
64
+ resource_id="shield:waf-associations",
65
+ actual_value="No WAF-eligible protected resources found",
66
+ remediation=""
67
+ ))
68
+ return self.findings
69
+
70
+ # Check each eligible resource for WAF association
71
+ for protection in waf_eligible_protections:
72
+ resource_arn = protection.get("ResourceArn", "")
73
+ protection_name = protection.get("Name", "Unknown")
74
+
75
+ # Determine the correct region for the WAF check
76
+ check_region = region
77
+ if "elasticloadbalancing" in resource_arn.lower():
78
+ # Extract region from ALB ARN: arn:aws:elasticloadbalancing:region:...
79
+ arn_parts = resource_arn.split(":")
80
+ if len(arn_parts) >= 4:
81
+ check_region = arn_parts[3]
82
+
83
+ web_acl = self.get_web_acl_for_resource(check_region, resource_arn)
84
+
85
+ if "Error" in web_acl:
86
+ error_code = web_acl["Error"].get("Code", "")
87
+ if error_code == "WAFNonexistentItemException":
88
+ self.findings.append(self.create_finding(
89
+ status="FAIL",
90
+ region=check_region,
91
+ resource_id=resource_arn,
92
+ actual_value="No WAF web ACL associated",
93
+ remediation="Associate a WAF web ACL with this resource for enhanced application layer protection"
94
+ ))
95
+ else:
96
+ self.findings.append(self.create_finding(
97
+ status="ERROR",
98
+ region=check_region,
99
+ resource_id=resource_arn,
100
+ actual_value=web_acl["Error"].get("Message", "Unknown error"),
101
+ remediation="Check IAM permissions for WAF API access"
102
+ ))
103
+ elif web_acl.get("WebACL"):
104
+ web_acl_name = web_acl["WebACL"].get("Name", "Unknown")
105
+ web_acl_id = web_acl["WebACL"].get("Id", "")
106
+ self.findings.append(self.create_finding(
107
+ status="PASS",
108
+ region=check_region,
109
+ resource_id=resource_arn,
110
+ actual_value=f"WAF web ACL associated: {web_acl_name} ({web_acl_id})",
111
+ remediation=""
112
+ ))
113
+ else:
114
+ self.findings.append(self.create_finding(
115
+ status="FAIL",
116
+ region=check_region,
117
+ resource_id=resource_arn,
118
+ actual_value="No WAF web ACL associated",
119
+ remediation="Associate a WAF web ACL with this resource for enhanced application layer protection"
120
+ ))
121
+ else:
122
+ self.findings.append(self.create_finding(
123
+ status="FAIL",
124
+ region=region,
125
+ resource_id=None,
126
+ actual_value="No Shield Advanced protections found",
127
+ remediation="Enable Shield Advanced protection for resources and associate WAF web ACLs"
128
+ ))
129
+
130
+ return self.findings