mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-13 00:05:04 +00:00
feat(CIS checks): Complete CIS checks (#1461)
Co-authored-by: sergargar <sergio@verica.io> Co-authored-by: Nacho Rivera <59198746+n4ch04@users.noreply.github.com> Co-authored-by: Pepe Fagoaga <pepe@verica.io>
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"Provider": "aws",
|
||||
"CheckID": "cloudtrail_s3_dataevents_write_enabled",
|
||||
"CheckTitle": "Check if S3 buckets have Object-level logging for write events is enabled in CloudTrail.",
|
||||
"CheckType": ["Logging and Monitoring"],
|
||||
"ServiceName": "s3",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
|
||||
"Severity": "low",
|
||||
"ResourceType": "AwsS3Bucket",
|
||||
"Description": "Ensure that all your AWS CloudTrail trails are configured to log Data events in order to record S3 object-level API operations, such as GetObject, DeleteObject and PutObject, for individual S3 buckets or for all current and future S3 buckets provisioned in your AWS account.",
|
||||
"Risk": "If logs are not enabled, monitoring of service use and threat analysis is not possible.",
|
||||
"RelatedUrl": "",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "aws cloudtrail put-event-selectors --trail-name <YOUR_TRAIL_NAME_HERE> --event-selectors '[{ 'ReadWriteType': 'WriteOnly', 'IncludeManagementEvents':true, 'DataResources': [{ 'Type': 'AWS::S3::Object', 'Values': ['arn:aws:s3'] }] }]'",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Enable logs. Create an S3 lifecycle policy. Define use cases, metrics and automated responses where applicable.",
|
||||
"Url": "https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-cloudtrail-logging-for-s3.html"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Tags": {
|
||||
"Tag1Key": "value",
|
||||
"Tag2Key": "value"
|
||||
},
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "",
|
||||
"Compliance": []
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.cloudtrail.cloudtrail_client import cloudtrail_client
|
||||
|
||||
|
||||
class cloudtrail_s3_dataevents_write_enabled(Check):
|
||||
def execute(self):
|
||||
findings = []
|
||||
report = Check_Report(self.metadata)
|
||||
report.region = cloudtrail_client.region
|
||||
report.resource_id = "No trails"
|
||||
report.resource_arn = "No trails"
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "No CloudTrail trails have a data event to record all S3 object-level API operations."
|
||||
for trail in cloudtrail_client.trails:
|
||||
for data_event in trail.data_events:
|
||||
# Check if trail has a data event for all S3 Buckets for write
|
||||
if (
|
||||
data_event["ReadWriteType"] == "All"
|
||||
or data_event["ReadWriteType"] == "WriteOnly"
|
||||
):
|
||||
for resource in data_event["DataResources"]:
|
||||
if "AWS::S3::Object" == resource["Type"] and (
|
||||
"arn:aws:s3" in resource["Values"]
|
||||
or "arn:aws:s3:::*/*" in resource["Values"]
|
||||
):
|
||||
report.region = trail.region
|
||||
report.resource_id = trail.name
|
||||
report.resource_arn = trail.arn
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"Trail {trail.name} have a data event to record all S3 object-level API operations."
|
||||
|
||||
findings.append(report)
|
||||
return findings
|
||||
@@ -0,0 +1,143 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_s3
|
||||
|
||||
|
||||
class Test_cloudtrail_s3_dataevents_write_enabled:
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_trail_without_data_events(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.cloudtrail.cloudtrail_service import Cloudtrail
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled import (
|
||||
cloudtrail_s3_dataevents_write_enabled,
|
||||
)
|
||||
|
||||
check = cloudtrail_s3_dataevents_write_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"No CloudTrail trails have a data event to record all S3 object-level API operations.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == "No trails"
|
||||
assert result[0].resource_arn == "No trails"
|
||||
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_trail_without_s3_data_events(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
_ = cloudtrail_client_us_east_1.put_event_selectors(
|
||||
TrailName=trail_name_us,
|
||||
EventSelectors=[
|
||||
{
|
||||
"ReadWriteType": "All",
|
||||
"IncludeManagementEvents": True,
|
||||
"DataResources": [
|
||||
{"Type": "AWS::Lambda::Function", "Values": ["arn:aws:lambda"]}
|
||||
],
|
||||
}
|
||||
],
|
||||
)["EventSelectors"]
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.cloudtrail.cloudtrail_service import Cloudtrail
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled import (
|
||||
cloudtrail_s3_dataevents_write_enabled,
|
||||
)
|
||||
|
||||
check = cloudtrail_s3_dataevents_write_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"No CloudTrail trails have a data event to record all S3 object-level API operations.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == "No trails"
|
||||
assert result[0].resource_arn == "No trails"
|
||||
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_trail_with_s3_data_events(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
trail_us = cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
_ = cloudtrail_client_us_east_1.put_event_selectors(
|
||||
TrailName=trail_name_us,
|
||||
EventSelectors=[
|
||||
{
|
||||
"ReadWriteType": "All",
|
||||
"IncludeManagementEvents": True,
|
||||
"DataResources": [
|
||||
{"Type": "AWS::S3::Object", "Values": ["arn:aws:s3:::*/*"]}
|
||||
],
|
||||
}
|
||||
],
|
||||
)["EventSelectors"]
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.cloudtrail.cloudtrail_service import Cloudtrail
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled import (
|
||||
cloudtrail_s3_dataevents_write_enabled,
|
||||
)
|
||||
|
||||
check = cloudtrail_s3_dataevents_write_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert search(
|
||||
"have a data event to record all S3 object-level API operations.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == trail_name_us
|
||||
assert result[0].resource_arn == trail_us["TrailARN"]
|
||||
Reference in New Issue
Block a user