-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(codebuild): add new check `codebuild_report_group_export_encrypt…
…ed` (#5384) Co-authored-by: Sergio Garcia <[email protected]> Co-authored-by: Sergio <[email protected]>
- Loading branch information
1 parent
aac6038
commit 78d2fb9
Showing
8 changed files
with
370 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
32 changes: 32 additions & 0 deletions
32
...build_report_group_export_encrypted/codebuild_report_group_export_encrypted.metadata.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"Provider": "aws", | ||
"CheckID": "codebuild_report_group_export_encrypted", | ||
"CheckTitle": "CodeBuild report group exports are encrypted at rest", | ||
"CheckType": [], | ||
"ServiceName": "codebuild", | ||
"SubServiceName": "", | ||
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", | ||
"Severity": "medium", | ||
"ResourceType": "Other", | ||
"Description": "Ensure that CodeBuild report group exports are encrypted at rest.", | ||
"Risk": "If CodeBuild report group exports are not encrypted, sensitive data could be exposed to unauthorized access.", | ||
"RelatedUrl": "https://docs.aws.amazon.com/codebuild/latest/userguide/report-group-export-settings.html", | ||
"Remediation": { | ||
"Code": { | ||
"CLI": "aws codebuild update-report-group --arn <report-group-arn> --export-config \"exportConfigType=S3, s3Destination={bucket=, encryptionDisabled=true}\"", | ||
"NativeIaC": "", | ||
"Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/codebuild-controls.html#codebuild-7", | ||
"Terraform": "" | ||
}, | ||
"Recommendation": { | ||
"Text": "Configure CodeBuild report group exports to use encryption at rest. This can be done by specifying a KMS key ID when creating or updating the report group.", | ||
"Url": "https://docs.aws.amazon.com/codebuild/latest/userguide/report-group-export-settings.html" | ||
} | ||
}, | ||
"Categories": [ | ||
"encryption" | ||
], | ||
"DependsOn": [], | ||
"RelatedTo": [], | ||
"Notes": "" | ||
} |
24 changes: 24 additions & 0 deletions
24
...ebuild/codebuild_report_group_export_encrypted/codebuild_report_group_export_encrypted.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
from prowler.lib.check.models import Check, Check_Report_AWS | ||
from prowler.providers.aws.services.codebuild.codebuild_client import codebuild_client | ||
|
||
|
||
class codebuild_report_group_export_encrypted(Check): | ||
def execute(self): | ||
findings = [] | ||
for report_group in codebuild_client.report_groups.values(): | ||
if report_group.export_config and report_group.export_config.type == "S3": | ||
report = Check_Report_AWS(self.metadata()) | ||
report.resource_id = report_group.name | ||
report.resource_arn = report_group.arn | ||
report.region = report_group.region | ||
report.resource_tags = report_group.tags | ||
report.status = "PASS" | ||
report.status_extended = f"CodeBuild report group {report_group.name} exports are encrypted at {report_group.export_config.bucket_location} with KMS key {report_group.export_config.encryption_key}." | ||
|
||
if not report_group.export_config.encrypted: | ||
report.status = "FAIL" | ||
report.status_extended = f"CodeBuild report group {report_group.name} exports are not encrypted at {report_group.export_config.bucket_location}." | ||
|
||
findings.append(report) | ||
|
||
return findings |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
179 changes: 179 additions & 0 deletions
179
...d/codebuild_report_group_export_encrypted/codebuild_report_group_export_encrypted_test.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
from unittest.mock import patch | ||
|
||
import botocore | ||
from moto import mock_aws | ||
|
||
from tests.providers.aws.utils import ( | ||
AWS_ACCOUNT_NUMBER, | ||
AWS_REGION_EU_WEST_1, | ||
set_mocked_aws_provider, | ||
) | ||
|
||
orig = botocore.client.BaseClient._make_api_call | ||
|
||
|
||
def mock_make_api_call_encrypted(self, operation_name, kwarg): | ||
if operation_name == "ListReportGroups": | ||
return { | ||
"reportGroups": [ | ||
f"arn:aws:codebuild:eu-west-1:{AWS_ACCOUNT_NUMBER}:report-group/test-report-group-encrypted" | ||
] | ||
} | ||
elif operation_name == "BatchGetReportGroups": | ||
return { | ||
"reportGroups": [ | ||
{ | ||
"name": "test-report-group-encrypted", | ||
"arn": f"arn:aws:codebuild:eu-west-1:{AWS_ACCOUNT_NUMBER}:report-group/test-report-group-encrypted", | ||
"exportConfig": { | ||
"exportConfigType": "S3", | ||
"s3Destination": { | ||
"bucket": "test-bucket", | ||
"path": "test-path", | ||
"encryptionKey": f"arn:aws:kms:eu-west-1:{AWS_ACCOUNT_NUMBER}:key/12345678-1234-1234-1234-{AWS_ACCOUNT_NUMBER}", | ||
"encryptionDisabled": False, | ||
}, | ||
}, | ||
"tags": [{"key": "Name", "value": "test-report-group-encrypted"}], | ||
"status": "ACTIVE", | ||
} | ||
] | ||
} | ||
# If we don't want to patch the API call | ||
return orig(self, operation_name, kwarg) | ||
|
||
|
||
def mock_make_api_call_not_encrypted(self, operation_name, kwarg): | ||
if operation_name == "ListReportGroups": | ||
return { | ||
"reportGroups": [ | ||
f"arn:aws:codebuild:eu-west-1:{AWS_ACCOUNT_NUMBER}:report-group/test-report-group-not-encrypted" | ||
] | ||
} | ||
elif operation_name == "BatchGetReportGroups": | ||
return { | ||
"reportGroups": [ | ||
{ | ||
"name": "test-report-group-not-encrypted", | ||
"arn": f"arn:aws:codebuild:eu-west-1:{AWS_ACCOUNT_NUMBER}:report-group/test-report-group-not-encrypted", | ||
"exportConfig": { | ||
"exportConfigType": "S3", | ||
"s3Destination": { | ||
"bucket": "test-bucket", | ||
"path": "test-path", | ||
"encryptionKey": "", | ||
"encryptionDisabled": True, | ||
}, | ||
}, | ||
"tags": [ | ||
{"key": "Name", "value": "test-report-group-not-encrypted"} | ||
], | ||
"status": "ACTIVE", | ||
} | ||
] | ||
} | ||
# If we don't want to patch the API call | ||
return orig(self, operation_name, kwarg) | ||
|
||
|
||
class Test_codebuild_report_group_export_encrypted: | ||
@mock_aws | ||
def test_no_report_groups(self): | ||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) | ||
|
||
from prowler.providers.aws.services.codebuild.codebuild_service import Codebuild | ||
|
||
with patch( | ||
"prowler.providers.common.provider.Provider.get_global_provider", | ||
return_value=aws_provider, | ||
), patch( | ||
"prowler.providers.aws.services.codebuild.codebuild_report_group_export_encrypted.codebuild_report_group_export_encrypted.codebuild_client", | ||
new=Codebuild(aws_provider), | ||
): | ||
from prowler.providers.aws.services.codebuild.codebuild_report_group_export_encrypted.codebuild_report_group_export_encrypted import ( | ||
codebuild_report_group_export_encrypted, | ||
) | ||
|
||
check = codebuild_report_group_export_encrypted() | ||
result = check.execute() | ||
|
||
assert len(result) == 0 | ||
|
||
@patch( | ||
"botocore.client.BaseClient._make_api_call", new=mock_make_api_call_encrypted | ||
) | ||
@mock_aws | ||
def test_report_group_export_encrypted(self): | ||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) | ||
|
||
from prowler.providers.aws.services.codebuild.codebuild_service import Codebuild | ||
|
||
with patch( | ||
"prowler.providers.common.provider.Provider.get_global_provider", | ||
return_value=aws_provider, | ||
), patch( | ||
"prowler.providers.aws.services.codebuild.codebuild_report_group_export_encrypted.codebuild_report_group_export_encrypted.codebuild_client", | ||
new=Codebuild(aws_provider), | ||
): | ||
from prowler.providers.aws.services.codebuild.codebuild_report_group_export_encrypted.codebuild_report_group_export_encrypted import ( | ||
codebuild_report_group_export_encrypted, | ||
) | ||
|
||
check = codebuild_report_group_export_encrypted() | ||
result = check.execute() | ||
|
||
assert len(result) == 1 | ||
assert result[0].status == "PASS" | ||
assert ( | ||
result[0].status_extended | ||
== f"CodeBuild report group test-report-group-encrypted exports are encrypted at s3://test-bucket/test-path with KMS key arn:aws:kms:eu-west-1:{AWS_ACCOUNT_NUMBER}:key/12345678-1234-1234-1234-{AWS_ACCOUNT_NUMBER}." | ||
) | ||
assert result[0].resource_id == "test-report-group-encrypted" | ||
assert ( | ||
result[0].resource_arn | ||
== f"arn:aws:codebuild:eu-west-1:{AWS_ACCOUNT_NUMBER}:report-group/test-report-group-encrypted" | ||
) | ||
assert result[0].resource_tags == [ | ||
{"key": "Name", "value": "test-report-group-encrypted"} | ||
] | ||
assert result[0].region == AWS_REGION_EU_WEST_1 | ||
|
||
@patch( | ||
"botocore.client.BaseClient._make_api_call", | ||
new=mock_make_api_call_not_encrypted, | ||
) | ||
@mock_aws | ||
def test_report_group_export_not_encrypted(self): | ||
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) | ||
|
||
from prowler.providers.aws.services.codebuild.codebuild_service import Codebuild | ||
|
||
with patch( | ||
"prowler.providers.common.provider.Provider.get_global_provider", | ||
return_value=aws_provider, | ||
), patch( | ||
"prowler.providers.aws.services.codebuild.codebuild_report_group_export_encrypted.codebuild_report_group_export_encrypted.codebuild_client", | ||
new=Codebuild(aws_provider), | ||
): | ||
from prowler.providers.aws.services.codebuild.codebuild_report_group_export_encrypted.codebuild_report_group_export_encrypted import ( | ||
codebuild_report_group_export_encrypted, | ||
) | ||
|
||
check = codebuild_report_group_export_encrypted() | ||
result = check.execute() | ||
|
||
assert len(result) == 1 | ||
assert result[0].status == "FAIL" | ||
assert ( | ||
result[0].status_extended | ||
== "CodeBuild report group test-report-group-not-encrypted exports are not encrypted at s3://test-bucket/test-path." | ||
) | ||
assert result[0].resource_id == "test-report-group-not-encrypted" | ||
assert ( | ||
result[0].resource_arn | ||
== f"arn:aws:codebuild:eu-west-1:{AWS_ACCOUNT_NUMBER}:report-group/test-report-group-not-encrypted" | ||
) | ||
assert result[0].resource_tags == [ | ||
{"key": "Name", "value": "test-report-group-not-encrypted"} | ||
] | ||
assert result[0].region == AWS_REGION_EU_WEST_1 |
Oops, something went wrong.