feat(aws): add new check for Codebuild projects visibility (#8127)

Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
This commit is contained in:
Neil Millard
2025-07-02 10:20:15 +01:00
committed by GitHub
parent f78a29206c
commit 965111245a
8 changed files with 238 additions and 0 deletions

View File

@@ -0,0 +1,176 @@
from unittest import mock
from prowler.providers.aws.services.codebuild.codebuild_service import Project
AWS_REGION = "eu-west-1"
AWS_ACCOUNT_NUMBER = "123456789012"
class Test_codebuild_project_not_publicly_accessible:
def test_project_public(self):
codebuild_client = mock.MagicMock
project_name = "test-project"
project_arn = f"arn:aws:codebuild:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:project/{project_name}"
codebuild_client.projects = {
project_arn: Project(
name=project_name,
arn=project_arn,
region="eu-west-1",
project_visibility="PUBLIC",
tags=[],
)
}
with (
mock.patch(
"prowler.providers.aws.services.codebuild.codebuild_service.Codebuild",
codebuild_client,
),
mock.patch(
"prowler.providers.aws.services.codebuild.codebuild_project_not_publicly_accessible.codebuild_project_not_publicly_accessible.codebuild_client",
codebuild_client,
),
):
from prowler.providers.aws.services.codebuild.codebuild_project_not_publicly_accessible.codebuild_project_not_publicly_accessible import (
codebuild_project_not_publicly_accessible,
)
check = codebuild_project_not_publicly_accessible()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"CodeBuild project {project_name} is public."
)
assert result[0].resource_id == project_name
assert result[0].resource_arn == project_arn
assert result[0].resource_tags == []
assert result[0].region == AWS_REGION
def test_project_private(self):
codebuild_client = mock.MagicMock
project_name = "test-project"
project_arn = f"arn:aws:codebuild:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:project/{project_name}"
codebuild_client.projects = {
project_arn: Project(
name=project_name,
arn=project_arn,
region="eu-west-1",
project_visibility="PRIVATE",
tags=[],
)
}
with (
mock.patch(
"prowler.providers.aws.services.codebuild.codebuild_service.Codebuild",
codebuild_client,
),
mock.patch(
"prowler.providers.aws.services.codebuild.codebuild_project_not_publicly_accessible.codebuild_project_not_publicly_accessible.codebuild_client",
codebuild_client,
),
):
from prowler.providers.aws.services.codebuild.codebuild_project_not_publicly_accessible.codebuild_project_not_publicly_accessible import (
codebuild_project_not_publicly_accessible,
)
check = codebuild_project_not_publicly_accessible()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"CodeBuild project {project_name} is private."
)
assert result[0].resource_id == project_name
assert result[0].resource_arn == project_arn
assert result[0].resource_tags == []
assert result[0].region == AWS_REGION
def test_project_no_visibility_set(self):
codebuild_client = mock.MagicMock
project_name = "test-project"
project_arn = f"arn:aws:codebuild:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:project/{project_name}"
codebuild_client.projects = {
project_arn: Project(
name=project_name,
arn=project_arn,
region="eu-west-1",
project_visibility=None,
tags=[],
)
}
with (
mock.patch(
"prowler.providers.aws.services.codebuild.codebuild_service.Codebuild",
codebuild_client,
),
mock.patch(
"prowler.providers.aws.services.codebuild.codebuild_project_not_publicly_accessible.codebuild_project_not_publicly_accessible.codebuild_client",
codebuild_client,
),
):
from prowler.providers.aws.services.codebuild.codebuild_project_not_publicly_accessible.codebuild_project_not_publicly_accessible import (
codebuild_project_not_publicly_accessible,
)
check = codebuild_project_not_publicly_accessible()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"CodeBuild project {project_name} is public."
)
assert result[0].resource_id == project_name
assert result[0].resource_arn == project_arn
assert result[0].resource_tags == []
assert result[0].region == AWS_REGION
def test_project_empty_visibility(self):
codebuild_client = mock.MagicMock
project_name = "test-project"
project_arn = f"arn:aws:codebuild:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:project/{project_name}"
codebuild_client.projects = {
project_arn: Project(
name=project_name,
arn=project_arn,
region="eu-west-1",
project_visibility="",
tags=[],
)
}
with (
mock.patch(
"prowler.providers.aws.services.codebuild.codebuild_service.Codebuild",
codebuild_client,
),
mock.patch(
"prowler.providers.aws.services.codebuild.codebuild_project_not_publicly_accessible.codebuild_project_not_publicly_accessible.codebuild_client",
codebuild_client,
),
):
from prowler.providers.aws.services.codebuild.codebuild_project_not_publicly_accessible.codebuild_project_not_publicly_accessible import (
codebuild_project_not_publicly_accessible,
)
check = codebuild_project_not_publicly_accessible()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"CodeBuild project {project_name} is public."
)
assert result[0].resource_id == project_name
assert result[0].resource_arn == project_arn
assert result[0].resource_tags == []
assert result[0].region == AWS_REGION

View File

@@ -28,6 +28,7 @@ build_id = "test:93f838a7-cd20-48ae-90e5-c10fbbc78ca6"
last_invoked_time = datetime.now() - timedelta(days=2)
bitbucket_url = "https://bitbucket.org/example/repo.git"
secondary_bitbucket_url = "https://bitbucket.org/example/secondary-repo.git"
project_visibility = "PRIVATE"
report_group_arn = f"arn:{AWS_COMMERCIAL_PARTITION}:codebuild:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:report-group/{project_name}"
@@ -71,6 +72,7 @@ def mock_make_api_call(self, operation_name, kwarg):
},
},
"tags": [{"key": "Name", "value": project_name}],
"projectVisibility": project_visibility,
}
]
}
@@ -152,6 +154,7 @@ class Test_Codebuild_Service:
)
assert codebuild.projects[project_arn].tags[0]["key"] == "Name"
assert codebuild.projects[project_arn].tags[0]["value"] == project_name
assert codebuild.projects[project_arn].project_visibility == project_visibility
# Asserttions related with report groups
assert len(codebuild.report_groups) == 1
assert isinstance(codebuild.report_groups, dict)