Skip to content

CloudFront distributions should have latest TLS version

Older TLS versions (1.0, 1.1, and early 1.2 cipher suites) have known vulnerabilities like BEAST, POODLE, and weak cipher negotiation. CloudFront distributions that allow these protocols expose end users to downgrade attacks and passive decryption by well-resourced adversaries.

Setting minimum_protocol_version to TLSv1.2_2021 restricts viewers to cipher suites that require forward secrecy across the board. This is a one-line Terraform change with no cost impact, but distributions left at defaults or legacy values silently accept connections from insecure clients, widening your attack surface for no practical benefit.

Retrofit consideration

This change can break clients that do not support TLS 1.2 with modern cipher suites, typically very old browsers or embedded devices. Before enforcing, check CloudFront real-time logs to confirm no legitimate traffic is still using deprecated protocols.

Implementation

Choose the approach that matches how you manage Terraform.

If you use terraform-aws-modules/cloudfront/aws, set the right module inputs for this control. You can later migrate to the compliance.tf module with minimal changes because it is compatible by design.

module "cloudfront" {
  source  = "terraform-aws-modules/cloudfront/aws"
  version = ">=6.0.0,<7.0.0"

  viewer_certificate = {
    minimum_protocol_version = "TLSv1.2_2021"
  }
}

Use AWS provider resources directly. See docs for the resources involved: aws_cloudfront_distribution.

resource "aws_cloudfront_distribution" "this" {
  default_cache_behavior {
    allowed_methods           = ["GET", "HEAD"]
    cached_methods            = ["GET", "HEAD"]
    field_level_encryption_id = "abc123"

    forwarded_values {
      cookies {
        forward = "none"
      }
      query_string = false
    }

    target_origin_id       = "S3Origin"
    viewer_protocol_policy = "redirect-to-https"
  }
  default_root_object = "index.html"
  enabled             = true

  logging_config {
    bucket = "example-bucket-abc123_domain_name"
  }

  origin {
    domain_name = "example.s3.amazonaws.com"
    origin_id   = "S3Origin"
  }

  restrictions {
    geo_restriction {
      locations        = ["US", "CA", "GB"]
      restriction_type = "whitelist"
    }
  }

  wait_for_deployment = false
  web_acl_id          = "arn:aws:wafv2:us-east-1:123456789012:regional/webacl/example/12345678-1234-1234-1234-123456789012"

  viewer_certificate {
    acm_certificate_arn      = "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
    minimum_protocol_version = "TLSv1.2_2021"
    ssl_support_method       = "sni-only"
  }
}

What this control checks

In the aws_cloudfront_distribution resource, the viewer_certificate block must set minimum_protocol_version to "TLSv1.2_2021". This argument only takes effect when cloudfront_default_certificate is false and ssl_support_method is "sni-only" (or "vip" for dedicated IP). When cloudfront_default_certificate is true, CloudFront uses its default certificate and minimum_protocol_version cannot be controlled; those distributions fail this control. Distributions specifying older values such as "TLSv1.2_2018", "TLSv1.2_2019", "TLSv1.1_2016", or "TLSv1_2016" also fail. Only "TLSv1.2_2021" passes.

Common pitfalls

  • Default certificate ignores minimum_protocol_version

    When cloudfront_default_certificate = true, the minimum_protocol_version argument is silently ignored. CloudFront uses its default *.cloudfront.net certificate, and you cannot control the protocol version in that configuration. To enforce TLSv1.2_2021, use a custom ACM certificate and set ssl_support_method = "sni-only".

  • Confusing similarly named policy values

    TLSv1.2_2019 and TLSv1.2_2018 both enforce TLS 1.2 but allow older cipher suites without requiring forward secrecy. Only TLSv1.2_2021 limits the cipher suite to ECDHE-based key exchange. Any other 1.2 variant still fails this control.

  • Origin protocol policy is separate

    This control covers viewer-to-CloudFront TLS only. The origin protocol policy (origin.custom_origin_config.origin_protocol_policy and origin_ssl_protocols) governs CloudFront-to-origin TLS and is not evaluated here. Both legs should be hardened independently.

Audit evidence

AWS Config rule results showing all distributions as compliant, or a CSPM inventory listing each distribution's ViewerCertificate.MinimumProtocolVersion value, both satisfy the point-in-time evidence requirement. Console evidence is a screenshot of the distribution's General tab with the security policy set to TLSv1.2_2021. CloudTrail UpdateDistribution events cover the continuous assurance angle, confirming no distribution was reconfigured to a weaker protocol version after the compliance baseline was set.

Tool mappings

Use these identifiers to cross-reference this control across tools, reports, and evidence.

  • Compliance.tf Control: cloudfront_distribution_latest_tls_version

  • AWS Config Managed Rules: CLOUDFRONT_SECURITY_POLICY_CHECK, CLOUDFRONT_SSL_POLICY_CHECK

  • Checkov Check: CKV_AWS_174

  • Powerpipe Controls: aws_compliance.control.cloudfront_distribution_latest_tls_version, aws_compliance.control.cloudfront_distribution_uses_recommended_tls_security_policy

  • AWS Security Hub Control: CloudFront.15

  • KICS Query: 00e5e55e-c2ff-46b3-a757-a7a1cd802456

  • Trivy Check: AWS-0013

Last reviewed: 2026-03-09