bp-check/services/cloudfront.py

153 lines
5.3 KiB
Python
Raw Normal View History

2024-08-14 01:05:06 +00:00
from models import RuleCheckResult, RuleChecker
from functools import cached_property
2024-08-05 02:30:34 +00:00
import boto3
2024-08-14 01:05:06 +00:00
class CloudFrontRuleChecker(RuleChecker):
def __init__(self):
self.client = boto3.client("cloudfront")
2024-08-05 02:30:34 +00:00
2024-08-14 01:05:06 +00:00
@cached_property
def distributions(self):
2024-08-14 04:21:46 +00:00
return self.client.list_distributions()["DistributionList"].get("Items", [])
2024-08-05 02:30:34 +00:00
2024-08-14 01:05:06 +00:00
@cached_property
def distribution_details(self):
responses = [
self.client.get_distribution(Id=distribution["Id"])["Distribution"]
for distribution in self.distributions
]
return {
distribution["Id"]: response
for distribution, response in zip(self.distributions, responses)
}
2024-08-07 11:40:35 +00:00
2024-08-14 01:05:06 +00:00
def cloudfront_accesslogs_enabled(self):
compliant_resources = []
non_compliant_resources = []
2024-08-07 11:40:35 +00:00
2024-08-14 01:05:06 +00:00
for distribution in self.distributions:
distribution = self.distribution_details[distribution["Id"]]
if (
"Logging" in distribution["DistributionConfig"]
and distribution["DistributionConfig"]["Logging"]["Enabled"] == True
):
compliant_resources.append(distribution["ARN"])
else:
non_compliant_resources.append(distribution["ARN"])
2024-08-05 02:30:34 +00:00
2024-08-14 01:05:06 +00:00
return RuleCheckResult(
passed=not non_compliant_resources,
compliant_resources=compliant_resources,
non_compliant_resources=non_compliant_resources,
)
2024-08-05 02:30:34 +00:00
2024-08-14 01:05:06 +00:00
def cloudfront_associated_with_waf(self):
compliant_resources = []
non_compliant_resources = []
2024-08-07 11:40:35 +00:00
2024-08-14 01:05:06 +00:00
for distribution in self.distributions:
if "WebACLId" in distribution and distribution["WebACLId"] != "":
compliant_resources.append(distribution["ARN"])
else:
non_compliant_resources.append(distribution["ARN"])
2024-08-07 11:40:35 +00:00
2024-08-14 01:05:06 +00:00
return RuleCheckResult(
passed=not non_compliant_resources,
compliant_resources=compliant_resources,
non_compliant_resources=non_compliant_resources,
)
2024-08-07 11:40:35 +00:00
2024-08-14 01:05:06 +00:00
def cloudfront_default_root_object_configured(self):
compliant_resources = []
non_compliant_resources = []
2024-08-05 02:30:34 +00:00
2024-08-14 01:05:06 +00:00
for distribution in self.distributions:
distribution = self.distribution_details[distribution["Id"]]
2024-08-05 02:30:34 +00:00
2024-08-14 01:05:06 +00:00
if distribution["DistributionConfig"]["DefaultRootObject"] != "":
compliant_resources.append(distribution["ARN"])
else:
non_compliant_resources.append(distribution["ARN"])
2024-08-07 11:40:35 +00:00
2024-08-14 01:05:06 +00:00
return RuleCheckResult(
passed=not non_compliant_resources,
compliant_resources=compliant_resources,
non_compliant_resources=non_compliant_resources,
)
def cloudfront_no_deprecated_ssl_protocols(self):
compliant_resources = []
non_compliant_resources = []
for distribution in self.distributions:
for origin in distribution["Origins"]["Items"]:
if (
"CustomOriginConfig" in origin
and origin["CustomOriginConfig"]["OriginProtocolPolicy"]
in ["https-only", "match-viewer"]
and "SSLv3"
in origin["CustomOriginConfig"]["OriginSslProtocols"]["Items"]
):
non_compliant_resources.append(distribution["ARN"])
break
else:
compliant_resources.append(distribution["ARN"])
return RuleCheckResult(
passed=not non_compliant_resources,
compliant_resources=compliant_resources,
non_compliant_resources=non_compliant_resources,
)
def cloudfront_s3_origin_access_control_enabled(self):
compliant_resources = []
non_compliant_resources = []
for distribution in self.distributions:
for origin in distribution["Origins"]["Items"]:
if "S3OriginConfig" in origin and origin["OriginAccessControlId"] == "":
non_compliant_resources.append(distribution["ARN"])
break
else:
compliant_resources.append(distribution["ARN"])
return RuleCheckResult(
passed=not non_compliant_resources,
compliant_resources=compliant_resources,
non_compliant_resources=non_compliant_resources,
)
def cloudfront_viewer_policy_https(self):
compliant_resources = []
non_compliant_resources = []
for distribution in self.distributions:
2024-08-07 11:40:35 +00:00
if (
2024-08-14 01:05:06 +00:00
distribution["DefaultCacheBehavior"]["ViewerProtocolPolicy"]
== "allow-all"
2024-08-07 11:40:35 +00:00
):
non_compliant_resources.append(distribution["ARN"])
2024-08-14 01:05:06 +00:00
continue
allow_alls = [
behavior
for behavior in distribution["CacheBehaviors"]["Items"]
if behavior["ViewerProtocolPolicy"] == "allow-all"
]
if allow_alls:
non_compliant_resources.append(distribution["ARN"])
2024-08-14 01:05:06 +00:00
continue
2024-08-05 02:30:34 +00:00
2024-08-14 01:05:06 +00:00
compliant_resources.append(distribution["ARN"])
2024-08-14 01:05:06 +00:00
return RuleCheckResult(
passed=not non_compliant_resources,
compliant_resources=compliant_resources,
non_compliant_resources=non_compliant_resources,
)
2024-08-07 11:40:35 +00:00
2024-08-14 01:05:06 +00:00
rule_checker = CloudFrontRuleChecker