Back to Checks
aws

CloudFront distribution uses a custom SSL/TLS certificate

cloudfront_distributions_custom_ssl_certificate
Service: cloudfrontSeverity: medium
OfficialBuilt-inVerified
Categories:encryption
Resource Type:AwsCloudFrontDistribution

CloudFront distributions are configured with a custom SSL/TLS certificate rather than the default *.cloudfront.net certificate for viewer connections.

Risk

Using the default certificate prevents HTTPS on your own hostnames, breaking hostname validation. Clients may face errors or avoid TLS, impacting authentication and availability. Control over TLS posture and domain-bound security headers is reduced, weakening confidentiality and user trust.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks cloudfront_distributions_custom_ssl_certificate

Recommendation

  • Use a custom SSL/TLS certificate covering your domains and configure aliases.
  • Enforce modern TLS policy, SNI, and HSTS; disable legacy protocols.
  • Apply least privilege to certificate lifecycle and rotate/monitor keys.

Remediation

CLI

aws cloudfront get-distribution-config --id <DISTRIBUTION_ID> --output json > current-config.json && echo 'Manually edit current-config.json to add Aliases and ViewerCertificate fields, then run:' && echo 'aws cloudfront update-distribution --id <DISTRIBUTION_ID> --distribution-config file://current-config.json --if-match $(aws cloudfront get-distribution-config --id <DISTRIBUTION_ID> --query "ETag" --output text)'

Terraform

resource "aws_cloudfront_distribution" "<example_resource_name>" {
  enabled = true

  origin {
    domain_name = "<example_origin_domain>"
    origin_id   = "origin1"
    s3_origin_config {}
  }

  default_cache_behavior {
    target_origin_id       = "origin1"
    viewer_protocol_policy = "redirect-to-https"
    forwarded_values { query_string = false }
  }

  aliases = ["<example_domain>"]  # CRITICAL: add CNAME covered by the cert

  viewer_certificate {
    acm_certificate_arn = "<example_certificate_arn>"  # CRITICAL: custom ACM cert (in us-east-1)
    ssl_support_method  = "sni-only"                    # CRITICAL: required with ACM cert
  }
}

NativeIaC

Resources:
  <example_resource_name>:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Enabled: true
        Origins:
          - Id: origin1
            DomainName: <example_origin_domain>
            S3OriginConfig: {}
        DefaultCacheBehavior:
          TargetOriginId: origin1
          ViewerProtocolPolicy: redirect-to-https
          ForwardedValues:
            QueryString: false
        Aliases:
          - <example_domain>  # CRITICAL: add an alternate domain name (CNAME) covered by the certificate
        ViewerCertificate:
          AcmCertificateArn: <example_certificate_arn>  # CRITICAL: attach custom ACM cert (must be in us-east-1)
          SslSupportMethod: sni-only  # CRITICAL: required when using ACM cert

Other

1Open the CloudFront console and select your distribution
2Go to the Settings/General tab and click Edit
3In Alternate domain name (CNAME), add <example_domain>
4In SSL certificate, choose Custom SSL certificate and select your ACM certificate (issued in us-east-1 and covering <example_domain>)
5Click Save/Yes, Edit and wait for the distribution to deploy

Check Code

from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.cloudfront.cloudfront_client import (
    cloudfront_client,
)


class cloudfront_distributions_custom_ssl_certificate(Check):
    def execute(self):
        findings = []
        for distribution in cloudfront_client.distributions.values():
            report = Check_Report_AWS(metadata=self.metadata(), resource=distribution)
            report.status = "PASS"
            report.status_extended = f"CloudFront Distribution {distribution.id} is using a custom SSL/TLS certificate."

            if distribution.default_certificate:
                report.status = "FAIL"
                report.status_extended = f"CloudFront Distribution {distribution.id} is using the default SSL/TLS certificate."

            findings.append(report)

        return findings