fix(aws): guard checks reading iam roles when unlisted (#12785)

This commit is contained in:
Pedro Martín
2026-09-11 08:37:20 +02:00
committed by GitHub
parent f9c02da90a
commit b378f15798
7 changed files with 77 additions and 4 deletions
@@ -1,4 +1,4 @@
from unittest.mock import patch
from unittest.mock import MagicMock, patch
from boto3 import client
from moto import mock_aws
@@ -182,6 +182,59 @@ class Test_codebuild_project_uses_allowed_github_organizations:
)
assert result[0].region == AWS_REGION_EU_WEST_1
@mock_aws
def test_project_github_with_unlisted_roles(self):
# iam:ListRoles denied leaves iam_client.roles as None.
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
codebuild_client = client("codebuild", region_name=AWS_REGION_EU_WEST_1)
codebuild_client.create_project(
name="test-project-github-unlisted-roles",
source={
"type": "GITHUB",
"location": "https://github.com/allowed-org/repo",
},
artifacts={"type": "NO_ARTIFACTS"},
environment={
"type": "LINUX_CONTAINER",
"image": "aws/codebuild/standard:4.0",
"computeType": "BUILD_GENERAL1_SMALL",
"environmentVariables": [],
},
serviceRole=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:role/codebuild-test-role",
)
from prowler.providers.aws.services.codebuild.codebuild_service import Codebuild
iam_client = MagicMock()
iam_client.roles = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=aws_provider,
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.codebuild_client",
new=Codebuild(aws_provider),
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.iam_client",
new=iam_client,
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.codebuild_client.audit_config",
{"codebuild_github_allowed_organizations": ["allowed-org"]},
),
):
from prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations import (
codebuild_project_uses_allowed_github_organizations,
)
assert (
len(codebuild_project_uses_allowed_github_organizations().execute())
== 0
)
@mock_aws
def test_project_github_no_codebuild_trusted_principal(self):
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
@@ -93,6 +93,10 @@ class Test_iam_role_service_trust_restricts_source_to_account:
"""An account with no roles produces no reports at all."""
assert len(_run([])) == 0
def test_unlisted_roles_produce_no_reports(self):
# iam:ListRoles denied leaves iam_client.roles as None.
assert len(_run(None)) == 0
def test_service_linked_role_skipped(self):
"""A service-linked role is excluded even when its trust policy would FAIL.
@@ -472,6 +472,19 @@ class Test_rolesanywhere_profile_restricts_session_permissions:
assert result[0].status == "MANUAL"
assert "could not be evaluated" in result[0].status_extended
def test_unscoped_profile_with_unlisted_roles_is_manual(self):
# iam:ListRoles denied leaves iam_client.roles as None.
patches = _patched(
_build_client({PROFILE_ARN: _profile(role_arns=[ADMIN_ROLE_ARN])})
)
patches[-1].new.roles = None
with _enter(patches):
result = _run()
assert len(result) == 1
assert result[0].status == "MANUAL"
assert ADMIN_ROLE_ARN in result[0].status_extended
assert "could not be evaluated" in result[0].status_extended
def test_unscoped_profile_without_roles_passes(self):
with _enter(_patched(_build_client({PROFILE_ARN: _profile(role_arns=[])}))):
result = _run()