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,233 @@
1
+ """
2
+ Base class for Inspector security checks.
3
+ """
4
+ from typing import List, Optional, Dict, Any
5
+ from sraverify.core.check import SecurityCheck
6
+ from sraverify.services.inspector.client import InspectorClient
7
+ from sraverify.core.logging import logger
8
+
9
+
10
+ class InspectorCheck(SecurityCheck):
11
+ """Base class for all Inspector security checks."""
12
+
13
+ # Class-level caches shared across all instances
14
+ _inspector_account_status = {}
15
+ _inspector_batch_account_status = {} # SRA-INSPECTOR-7
16
+ _inspector_delegated_admin = {}
17
+ _inspector_org_config = {}
18
+ _organization_members = {}
19
+
20
+ def __init__(self):
21
+ """Initialize Inspector base check."""
22
+ super().__init__(
23
+ account_type="application", # Default, can be overridden in subclasses
24
+ service="Inspector",
25
+ resource_type="AWS::Inspector::Assessment"
26
+ )
27
+
28
+ def _setup_clients(self):
29
+ """Set up Inspector clients for each region."""
30
+ # Clear existing clients
31
+ self._clients.clear()
32
+ # Set up new clients only if regions are initialized
33
+ if hasattr(self, 'regions') and self.regions:
34
+ for region in self.regions:
35
+ self._clients[region] = InspectorClient(region, session=self.session)
36
+
37
+ def get_client(self, region: str) -> Optional[InspectorClient]:
38
+ """
39
+ Get Inspector client for a specific region.
40
+
41
+ Args:
42
+ region: AWS region name
43
+
44
+ Returns:
45
+ InspectorClient for the region or None if not available
46
+ """
47
+ return self._clients.get(region)
48
+
49
+ def get_account_status(self, region: str) -> Dict[str, Any]:
50
+ """
51
+ Get Inspector account status with caching.
52
+
53
+ Args:
54
+ region: AWS region name
55
+
56
+ Returns:
57
+ Dictionary containing account status
58
+ """
59
+ account_id = self.account_id
60
+ if not account_id:
61
+ logger.warning("Could not determine account ID")
62
+ return {}
63
+
64
+ # Check cache first
65
+ cache_key = f"{account_id}:{region}"
66
+ if cache_key in self.__class__._inspector_account_status:
67
+ logger.debug(f"Using cached Inspector account status for {cache_key}")
68
+ return self.__class__._inspector_account_status[cache_key]
69
+
70
+ client = self.get_client(region)
71
+ if not client:
72
+ logger.warning(f"No Inspector client available for region {region}")
73
+ return {}
74
+
75
+ # Get account status from client
76
+ response = client.batch_get_account_status(account_ids=[account_id])
77
+
78
+ # Extract the account status for the current account
79
+ account_status = {}
80
+ for status in response.get('accounts', []):
81
+ if status.get('accountId') == account_id:
82
+ # Restructure the account status to make it easier to access
83
+ account_status = {
84
+ 'accountId': status.get('accountId'),
85
+ 'state': status.get('state', {}),
86
+ # Extract resource states to top level for easier access in checks
87
+ 'ec2': status.get('resourceState', {}).get('ec2', {}),
88
+ 'ecr': status.get('resourceState', {}).get('ecr', {}),
89
+ 'lambda': status.get('resourceState', {}).get('lambda', {}),
90
+ 'lambdaCode': status.get('resourceState', {}).get('lambdaCode', {})
91
+ }
92
+ break
93
+
94
+ # Cache the result
95
+ self.__class__._inspector_account_status[cache_key] = account_status
96
+ logger.debug(f"Cached Inspector account status for {cache_key}")
97
+
98
+ return account_status
99
+
100
+ def get_delegated_admin(self, region: str) -> Dict[str, Any]:
101
+ """
102
+ Get Inspector delegated admin with caching.
103
+
104
+ Args:
105
+ region: AWS region name
106
+
107
+ Returns:
108
+ Dictionary containing delegated admin information
109
+ """
110
+ # Check cache first
111
+ cache_key = f"{self.session.region_name}:{region}"
112
+ if cache_key in self.__class__._inspector_delegated_admin:
113
+ logger.debug(f"Using cached Inspector delegated admin for {cache_key}")
114
+ return self.__class__._inspector_delegated_admin[cache_key]
115
+
116
+ client = self.get_client(region)
117
+ if not client:
118
+ logger.warning(f"No Inspector client available for region {region}")
119
+ return {}
120
+
121
+ # Get delegated admin from client
122
+ response = client.get_delegated_admin_account()
123
+
124
+ # Cache the result
125
+ self.__class__._inspector_delegated_admin[cache_key] = response
126
+ logger.debug(f"Cached Inspector delegated admin for {cache_key}")
127
+
128
+ return response
129
+
130
+ def get_organization_members(self, region: str) -> List[Dict[str, Any]]:
131
+ """
132
+ Get all AWS Organization member accounts with caching.
133
+
134
+ Args:
135
+ region: AWS region name (not used for Organizations API call)
136
+
137
+ Returns:
138
+ List of organization member accounts
139
+ """
140
+ # Use the current session region for Organizations API call
141
+ current_region = self.session.region_name
142
+
143
+ # Check cache first
144
+ cache_key = f"{current_region}:organizations"
145
+ if cache_key in self.__class__._organization_members:
146
+ logger.debug(f"Using cached organization members for {cache_key}")
147
+ return self.__class__._organization_members[cache_key]
148
+
149
+ # Use the client for the current region
150
+ client = self.get_client(current_region)
151
+ if not client:
152
+ logger.warning(f"No Inspector client available for region {current_region}")
153
+ return []
154
+
155
+ # Get organization members from client
156
+ accounts = client.list_organization_accounts()
157
+
158
+ # Cache the result
159
+ self.__class__._organization_members[cache_key] = accounts
160
+ logger.debug(f"Cached {len(accounts)} organization members for {cache_key} (using current region)")
161
+
162
+ return accounts
163
+
164
+ def batch_get_account_status(self, region: str, account_ids: List[str]) -> Dict[str, Dict]:
165
+ """
166
+ Get Inspector account status for multiple accounts with caching.
167
+
168
+ Args:
169
+ region: AWS region name
170
+ account_ids: List of account IDs to check
171
+
172
+ Returns:
173
+ Dictionary mapping account IDs to their status
174
+ """
175
+ # Check cache first
176
+ cache_key = f"{self.session.region_name}:{region}:batch_status"
177
+ if cache_key in self.__class__._inspector_batch_account_status:
178
+ logger.debug(f"Using cached Inspector batch account status for {cache_key}")
179
+ return self.__class__._inspector_batch_account_status[cache_key]
180
+
181
+ client = self.get_client(region)
182
+ if not client:
183
+ logger.warning(f"No Inspector client available for region {region}")
184
+ return {}
185
+
186
+ # Process accounts in batches of 10 (API limit)
187
+ result = {}
188
+ for i in range(0, len(account_ids), 10):
189
+ batch = account_ids[i:i+10]
190
+ try:
191
+ response = client.batch_get_account_status(batch)
192
+ for account in response.get('accounts', []):
193
+ acc_id = account.get('accountId')
194
+ if acc_id:
195
+ result[acc_id] = account
196
+ except Exception as e:
197
+ logger.debug(f"Error getting batch account status in {region}: {e}")
198
+
199
+ # Cache the result
200
+ self.__class__._inspector_batch_account_status[cache_key] = result
201
+ logger.debug(f"Cached Inspector batch account status for {len(result)} accounts in {region}")
202
+
203
+ return result
204
+
205
+ def get_organization_configuration(self, region: str) -> Dict[str, Any]:
206
+ """
207
+ Get Inspector organization configuration with caching.
208
+
209
+ Args:
210
+ region: AWS region name
211
+
212
+ Returns:
213
+ Dictionary containing organization configuration
214
+ """
215
+ # Check cache first
216
+ cache_key = f"{self.session.region_name}:{region}"
217
+ if cache_key in self.__class__._inspector_org_config:
218
+ logger.debug(f"Using cached Inspector organization configuration for {cache_key}")
219
+ return self.__class__._inspector_org_config[cache_key]
220
+
221
+ client = self.get_client(region)
222
+ if not client:
223
+ logger.warning(f"No Inspector client available for region {region}")
224
+ return {}
225
+
226
+ # Get organization configuration from client
227
+ response = client.describe_organization_configuration()
228
+
229
+ # Cache the result
230
+ self.__class__._inspector_org_config[cache_key] = response
231
+ logger.debug(f"Cached Inspector organization configuration for {cache_key}")
232
+
233
+ return response
@@ -0,0 +1,3 @@
1
+ """
2
+ Inspector security checks.
3
+ """
@@ -0,0 +1,69 @@
1
+ """
2
+ SRA-INSPECTOR-01: Inspector Service Status.
3
+ """
4
+ from typing import List, Dict, Any
5
+ from sraverify.services.inspector.base import InspectorCheck
6
+ from sraverify.core.logging import logger
7
+
8
+
9
+ class SRA_INSPECTOR_01(InspectorCheck):
10
+ """Check if Inspector service is enabled for the account."""
11
+
12
+ def __init__(self):
13
+ """Initialize the check."""
14
+ super().__init__()
15
+ self.check_id = "SRA-INSPECTOR-01"
16
+ self.check_name = "Inspector service is enabled"
17
+ self.account_type = "application"
18
+ self.severity = "HIGH"
19
+ self.description = (
20
+ "This check verifies whether Inspector service status for the account is enabled. "
21
+ "Amazon Inspector is a vulnerability management service that continuously scans your AWS "
22
+ "workloads for software vulnerabilities and unintended network exposure."
23
+ )
24
+ self.check_logic = (
25
+ "Check runs inspector2 batch-get-account-status. Check PASS if response state status = Enabled"
26
+ )
27
+
28
+ def execute(self) -> List[Dict[str, Any]]:
29
+ """
30
+ Execute the check.
31
+
32
+ Returns:
33
+ List of findings
34
+ """
35
+
36
+ for region in self.regions:
37
+ # Get account status using the base class method with caching
38
+ account_status = self.get_account_status(region)
39
+
40
+ # Check if state status is enabled
41
+ state_status = account_status.get('state', {}).get('status')
42
+
43
+ if not account_status or state_status != 'ENABLED':
44
+ self.findings.append(
45
+ self.create_finding(
46
+ status="FAIL",
47
+ region=region,
48
+ resource_id=f"inspector2/{self.account_id}",
49
+ checked_value="Inspector state status: ENABLED",
50
+ actual_value=f"Inspector state status: {state_status if state_status else 'NOT_ENABLED'}",
51
+ remediation=(
52
+ "Enable Amazon Inspector for your account using the AWS Console or CLI command: "
53
+ f"aws inspector2 enable --account-ids {self.account_id} --resource-types EC2 ECR LAMBDA LAMBDA_CODE --region {region}"
54
+ )
55
+ )
56
+ )
57
+ else:
58
+ self.findings.append(
59
+ self.create_finding(
60
+ status="PASS",
61
+ region=region,
62
+ resource_id=f"inspector2/{self.account_id}",
63
+ checked_value="Inspector state status: ENABLED",
64
+ actual_value=f"Inspector state status: {state_status}",
65
+ remediation="No remediation needed"
66
+ )
67
+ )
68
+
69
+ return self.findings
@@ -0,0 +1,68 @@
1
+ """
2
+ SRA-INSPECTOR-02: Inspector EC2 Vulnerability Scanning.
3
+ """
4
+ from typing import List, Dict, Any
5
+ from sraverify.services.inspector.base import InspectorCheck
6
+ from sraverify.core.logging import logger
7
+
8
+
9
+ class SRA_INSPECTOR_02(InspectorCheck):
10
+ """Check if Inspector EC2 vulnerability scanning is enabled for the account."""
11
+
12
+ def __init__(self):
13
+ """Initialize the check."""
14
+ super().__init__()
15
+ self.check_id = "SRA-INSPECTOR-02"
16
+ self.check_name = "Inspector EC2 vulnerability scanning is enabled"
17
+ self.account_type = "application"
18
+ self.severity = "HIGH"
19
+ self.description = (
20
+ "This check verifies whether Inspector EC2 vulnerability scanning feature is enabled. "
21
+ "Inspector automatically discovers EC2 instances and scans for software vulnerability."
22
+ )
23
+ self.check_logic = (
24
+ "Check runs inspector2 batch-get-account-status. Check PASS if response ec2 status = ENABLED"
25
+ )
26
+
27
+ def execute(self) -> List[Dict[str, Any]]:
28
+ """
29
+ Execute the check.
30
+
31
+ Returns:
32
+ List of findings
33
+ """
34
+
35
+ for region in self.regions:
36
+ # Get account status using the base class method with caching
37
+ account_status = self.get_account_status(region)
38
+
39
+ # Check if EC2 scanning is enabled
40
+ ec2_status = account_status.get('ec2', {}).get('status')
41
+
42
+ if not account_status or ec2_status != 'ENABLED':
43
+ self.findings.append(
44
+ self.create_finding(
45
+ status="FAIL",
46
+ region=region,
47
+ resource_id=f"inspector2/{self.account_id}/ec2",
48
+ checked_value="Inspector EC2 scanning: ENABLED",
49
+ actual_value=f"Inspector EC2 scanning: {ec2_status if ec2_status else 'NOT_ENABLED'}",
50
+ remediation=(
51
+ "Enable Amazon Inspector EC2 scanning for your account using the AWS Console or CLI command: "
52
+ f"aws inspector2 enable --account-ids {self.account_id} --resource-types EC2 --region {region}"
53
+ )
54
+ )
55
+ )
56
+ else:
57
+ self.findings.append(
58
+ self.create_finding(
59
+ status="PASS",
60
+ region=region,
61
+ resource_id=f"inspector2/{self.account_id}/ec2",
62
+ checked_value="Inspector EC2 scanning: ENABLED",
63
+ actual_value=f"Inspector EC2 scanning: {ec2_status}",
64
+ remediation="No remediation needed"
65
+ )
66
+ )
67
+
68
+ return self.findings
@@ -0,0 +1,68 @@
1
+ """
2
+ SRA-INSPECTOR-03: Inspector ECR Image Vulnerability Scanning.
3
+ """
4
+ from typing import List, Dict, Any
5
+ from sraverify.services.inspector.base import InspectorCheck
6
+ from sraverify.core.logging import logger
7
+
8
+
9
+ class SRA_INSPECTOR_03(InspectorCheck):
10
+ """Check if Inspector ECR image vulnerability scanning is enabled for the account."""
11
+
12
+ def __init__(self):
13
+ """Initialize the check."""
14
+ super().__init__()
15
+ self.check_id = "SRA-INSPECTOR-03"
16
+ self.check_name = "Inspector ECR image vulnerability scanning is enabled"
17
+ self.account_type = "application"
18
+ self.severity = "HIGH"
19
+ self.description = (
20
+ "This check verifies whether Inspector ECR image vulnerability scanning feature is enabled. "
21
+ "Amazon Inspector scans container images stored in Amazon ECR for software vulnerabilities to generate findings."
22
+ )
23
+ self.check_logic = (
24
+ "Check runs inspector2 batch-get-account-status. Check PASS if ecr status = ENABLED"
25
+ )
26
+
27
+ def execute(self) -> List[Dict[str, Any]]:
28
+ """
29
+ Execute the check.
30
+
31
+ Returns:
32
+ List of findings
33
+ """
34
+
35
+ for region in self.regions:
36
+ # Get account status using the base class method with caching
37
+ account_status = self.get_account_status(region)
38
+
39
+ # Check if ECR scanning is enabled
40
+ ecr_status = account_status.get('ecr', {}).get('status')
41
+
42
+ if not account_status or ecr_status != 'ENABLED':
43
+ self.findings.append(
44
+ self.create_finding(
45
+ status="FAIL",
46
+ region=region,
47
+ resource_id=f"inspector2/{self.account_id}/ecr",
48
+ checked_value="Inspector ECR scanning: ENABLED",
49
+ actual_value=f"Inspector ECR scanning: {ecr_status if ecr_status else 'NOT_ENABLED'}",
50
+ remediation=(
51
+ "Enable Amazon Inspector ECR scanning for your account using the AWS Console or CLI command: "
52
+ f"aws inspector2 enable --account-ids {self.account_id} --resource-types ECR --region {region}"
53
+ )
54
+ )
55
+ )
56
+ else:
57
+ self.findings.append(
58
+ self.create_finding(
59
+ status="PASS",
60
+ region=region,
61
+ resource_id=f"inspector2/{self.account_id}/ecr",
62
+ checked_value="Inspector ECR scanning: ENABLED",
63
+ actual_value=f"Inspector ECR scanning: {ecr_status}",
64
+ remediation="No remediation needed"
65
+ )
66
+ )
67
+
68
+ return self.findings
@@ -0,0 +1,70 @@
1
+ """
2
+ SRA-INSPECTOR-04: Inspector Lambda Function and Layers Vulnerability Scanning.
3
+ """
4
+ from typing import List, Dict, Any
5
+ from sraverify.services.inspector.base import InspectorCheck
6
+ from sraverify.core.logging import logger
7
+
8
+
9
+ class SRA_INSPECTOR_04(InspectorCheck):
10
+ """Check if Inspector Lambda function and layers vulnerability scanning is enabled for the account."""
11
+
12
+ def __init__(self):
13
+ """Initialize the check."""
14
+ super().__init__()
15
+ self.check_id = "SRA-INSPECTOR-04"
16
+ self.check_name = "Inspector Lambda function and layers vulnerability scanning is enabled"
17
+ self.account_type = "application"
18
+ self.severity = "HIGH"
19
+ self.description = (
20
+ "This check verifies whether Inspector Lambda function and layers for package and code vulnerability. "
21
+ "Amazon Inspector monitors each Lambda function throughout its lifetime until it's either deleted or excluded from scanning."
22
+ )
23
+ self.check_logic = (
24
+ "Check runs inspector2 batch-get-account-status. Check PASS if lambda status = ENABLED AND lambdaCode status = ENABLED"
25
+ )
26
+
27
+ def execute(self) -> List[Dict[str, Any]]:
28
+ """
29
+ Execute the check.
30
+
31
+ Returns:
32
+ List of findings
33
+ """
34
+
35
+ for region in self.regions:
36
+ # Get account status using the base class method with caching
37
+ account_status = self.get_account_status(region)
38
+
39
+ # Check if Lambda and LambdaCode scanning are enabled
40
+ lambda_status = account_status.get('lambda', {}).get('status')
41
+ lambda_code_status = account_status.get('lambdaCode', {}).get('status')
42
+
43
+ if not account_status or lambda_status != 'ENABLED' or lambda_code_status != 'ENABLED':
44
+ self.findings.append(
45
+ self.create_finding(
46
+ status="FAIL",
47
+ region=region,
48
+ resource_id=f"inspector2/{self.account_id}/lambda",
49
+ checked_value="Inspector Lambda scanning: ENABLED, LambdaCode scanning: ENABLED",
50
+ actual_value=f"Inspector Lambda scanning: {lambda_status if lambda_status else 'NOT_ENABLED'}, "
51
+ f"LambdaCode scanning: {lambda_code_status if lambda_code_status else 'NOT_ENABLED'}",
52
+ remediation=(
53
+ "Enable Amazon Inspector Lambda and LambdaCode scanning for your account using the AWS Console or CLI command: "
54
+ f"aws inspector2 enable --account-ids {self.account_id} --resource-types LAMBDA LAMBDA_CODE --region {region}"
55
+ )
56
+ )
57
+ )
58
+ else:
59
+ self.findings.append(
60
+ self.create_finding(
61
+ status="PASS",
62
+ region=region,
63
+ resource_id=f"inspector2/{self.account_id}/lambda",
64
+ checked_value="Inspector Lambda scanning: ENABLED, LambdaCode scanning: ENABLED",
65
+ actual_value=f"Inspector Lambda scanning: {lambda_status}, LambdaCode scanning: {lambda_code_status}",
66
+ remediation="No remediation needed"
67
+ )
68
+ )
69
+
70
+ return self.findings
@@ -0,0 +1,69 @@
1
+ """
2
+ SRA-INSPECTOR-05: Inspector Delegated Admin Account is Configured.
3
+ """
4
+ from typing import List, Dict, Any
5
+ from sraverify.services.inspector.base import InspectorCheck
6
+ from sraverify.core.logging import logger
7
+
8
+
9
+ class SRA_INSPECTOR_05(InspectorCheck):
10
+ """Check if Inspector delegated admin account is configured."""
11
+
12
+ def __init__(self):
13
+ """Initialize the check."""
14
+ super().__init__()
15
+ self.check_id = "SRA-INSPECTOR-05"
16
+ self.check_name = "Inspector delegated admin account is configured"
17
+ self.account_type = "management"
18
+ self.severity = "HIGH"
19
+ self.description = (
20
+ "This check verifies whether a delegated administrator account is configured for Amazon Inspector. "
21
+ "A delegated administrator can manage Inspector findings across all accounts in the organization."
22
+ )
23
+ self.check_logic = (
24
+ "Check runs inspector2 get-delegated-admin-account. Check PASS if response contains delegatedAdmin"
25
+ )
26
+
27
+ def execute(self) -> List[Dict[str, Any]]:
28
+ """
29
+ Execute the check.
30
+
31
+ Returns:
32
+ List of findings
33
+ """
34
+
35
+ # Check each region separately
36
+ for region in self.regions:
37
+ # Get delegated admin account for this region
38
+ delegated_admin_response = self.get_delegated_admin(region)
39
+ delegated_admin = delegated_admin_response.get('delegatedAdmin', {})
40
+ delegated_admin_id = delegated_admin.get('accountId')
41
+
42
+ if not delegated_admin_id:
43
+ self.findings.append(
44
+ self.create_finding(
45
+ status="FAIL",
46
+ region=region,
47
+ resource_id=f"inspector2/{region}/delegated-admin",
48
+ checked_value="Inspector delegated admin account is configured",
49
+ actual_value="No delegated admin account is configured",
50
+ remediation=(
51
+ "Configure a delegated admin account for Inspector using the AWS Console or CLI command: "
52
+ f"aws organizations register-delegated-administrator --account-id <AUDIT_ACCOUNT_ID> "
53
+ f"--service-principal inspector2.amazonaws.com --region {region}"
54
+ )
55
+ )
56
+ )
57
+ else:
58
+ self.findings.append(
59
+ self.create_finding(
60
+ status="PASS",
61
+ region=region,
62
+ resource_id=f"inspector2/{region}/delegated-admin",
63
+ checked_value="Inspector delegated admin account is configured",
64
+ actual_value=f"Delegated admin account {delegated_admin_id} is configured",
65
+ remediation="No remediation needed"
66
+ )
67
+ )
68
+
69
+ return self.findings