Skip to content

Commit 1187842

Browse files
committed
fix(aws): guard checks reading iam roles when unlisted
1 parent f9c02da commit 1187842

7 files changed

Lines changed: 77 additions & 4 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
`rolesanywhere_profile_restricts_session_permissions`, `iam_role_service_trust_restricts_source_to_account` and `codebuild_project_uses_allowed_github_organizations` crashing with `TypeError` when `iam:ListRoles` is denied

prowler/providers/aws/services/codebuild/codebuild_project_uses_allowed_github_organizations/codebuild_project_uses_allowed_github_organizations.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def execute(self):
2323
project_role = next(
2424
(
2525
role
26-
for role in iam_client.roles
26+
for role in iam_client.roles or []
2727
if role.arn == project.service_role_arn
2828
),
2929
None,

prowler/providers/aws/services/iam/iam_role_service_trust_restricts_source_to_account/iam_role_service_trust_restricts_source_to_account.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ def execute(self) -> Check_Report_AWS:
377377
status. The sibling token-wildcard check carries the same note, for the same reason.
378378
"""
379379
findings = []
380-
for role in iam_client.roles:
380+
for role in iam_client.roles or []:
381381
# Service-linked roles are excluded: their trust relationship is managed by
382382
# the service and cannot be edited, so a finding would not be actionable.
383383
if "aws-service-role" in role.arn:

prowler/providers/aws/services/rolesanywhere/rolesanywhere_profile_restricts_session_permissions/rolesanywhere_profile_restricts_session_permissions.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,9 @@ def execute(self) -> list[Check_Report_AWS]:
205205
not administrative, and disabled profiles.
206206
"""
207207
findings = []
208-
roles_by_arn = {role.arn: role for role in iam_client.roles}
208+
# iam:ListRoles denied leaves roles as None: every referenced role is
209+
# then unknown and the profile falls through to MANUAL.
210+
roles_by_arn = {role.arn: role for role in (iam_client.roles or [])}
209211
for profile in rolesanywhere_client.profiles.values():
210212
report = Check_Report_AWS(metadata=self.metadata(), resource=profile)
211213
role_statuses = {

tests/providers/aws/services/codebuild/codebuild_project_uses_allowed_github_organizations/codebuild_project_uses_allowed_github_organizations_test.py

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from unittest.mock import patch
1+
from unittest.mock import MagicMock, patch
22

33
from boto3 import client
44
from moto import mock_aws
@@ -182,6 +182,59 @@ def test_project_github_not_allowed_organization(self):
182182
)
183183
assert result[0].region == AWS_REGION_EU_WEST_1
184184

185+
@mock_aws
186+
def test_project_github_with_unlisted_roles(self):
187+
# iam:ListRoles denied leaves iam_client.roles as None.
188+
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
189+
codebuild_client = client("codebuild", region_name=AWS_REGION_EU_WEST_1)
190+
codebuild_client.create_project(
191+
name="test-project-github-unlisted-roles",
192+
source={
193+
"type": "GITHUB",
194+
"location": "https://github.com/allowed-org/repo",
195+
},
196+
artifacts={"type": "NO_ARTIFACTS"},
197+
environment={
198+
"type": "LINUX_CONTAINER",
199+
"image": "aws/codebuild/standard:4.0",
200+
"computeType": "BUILD_GENERAL1_SMALL",
201+
"environmentVariables": [],
202+
},
203+
serviceRole=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:role/codebuild-test-role",
204+
)
205+
206+
from prowler.providers.aws.services.codebuild.codebuild_service import Codebuild
207+
208+
iam_client = MagicMock()
209+
iam_client.roles = None
210+
211+
with (
212+
patch(
213+
"prowler.providers.common.provider.Provider.get_global_provider",
214+
return_value=aws_provider,
215+
),
216+
patch(
217+
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.codebuild_client",
218+
new=Codebuild(aws_provider),
219+
),
220+
patch(
221+
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.iam_client",
222+
new=iam_client,
223+
),
224+
patch(
225+
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.codebuild_client.audit_config",
226+
{"codebuild_github_allowed_organizations": ["allowed-org"]},
227+
),
228+
):
229+
from prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations import (
230+
codebuild_project_uses_allowed_github_organizations,
231+
)
232+
233+
assert (
234+
len(codebuild_project_uses_allowed_github_organizations().execute())
235+
== 0
236+
)
237+
185238
@mock_aws
186239
def test_project_github_no_codebuild_trusted_principal(self):
187240
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])

tests/providers/aws/services/iam/iam_role_service_trust_restricts_source_to_account/iam_role_service_trust_restricts_source_to_account_test.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ def test_no_roles(self):
9393
"""An account with no roles produces no reports at all."""
9494
assert len(_run([])) == 0
9595

96+
def test_unlisted_roles_produce_no_reports(self):
97+
# iam:ListRoles denied leaves iam_client.roles as None.
98+
assert len(_run(None)) == 0
99+
96100
def test_service_linked_role_skipped(self):
97101
"""A service-linked role is excluded even when its trust policy would FAIL.
98102

tests/providers/aws/services/rolesanywhere/rolesanywhere_profile_restricts_session_permissions/rolesanywhere_profile_restricts_session_permissions_test.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,19 @@ def test_unscoped_profile_with_unknown_role_is_manual(self):
472472
assert result[0].status == "MANUAL"
473473
assert "could not be evaluated" in result[0].status_extended
474474

475+
def test_unscoped_profile_with_unlisted_roles_is_manual(self):
476+
# iam:ListRoles denied leaves iam_client.roles as None.
477+
patches = _patched(
478+
_build_client({PROFILE_ARN: _profile(role_arns=[ADMIN_ROLE_ARN])})
479+
)
480+
patches[-1].new.roles = None
481+
with _enter(patches):
482+
result = _run()
483+
assert len(result) == 1
484+
assert result[0].status == "MANUAL"
485+
assert ADMIN_ROLE_ARN in result[0].status_extended
486+
assert "could not be evaluated" in result[0].status_extended
487+
475488
def test_unscoped_profile_without_roles_passes(self):
476489
with _enter(_patched(_build_client({PROFILE_ARN: _profile(role_arns=[])}))):
477490
result = _run()

0 commit comments

Comments
 (0)