CloudFrontCDN SecurityEdge SecurityWAFOrigin Access Control

AWS CloudFront Security: Protecting Your Content Delivery at the Edge

Vigilare Engineering

Platform Team · January 23, 2026 · 9 min read

Why CloudFront Security Deserves Dedicated Attention

CloudFront sits in front of your entire application stack, handling TLS termination, caching, and request routing before anything reaches your origin. This makes it both a critical security layer and a potential vulnerability: misconfigured CloudFront can expose your S3 buckets to the public, allow unauthorized access to restricted content, or let attackers bypass your WAF protection by hitting your origin directly.

This guide covers the security controls specific to CloudFront and how to monitor for the issues that arise when they're not properly configured.

Origin Access Control: Protecting Your S3 Origins

The most common CloudFront security misconfiguration is an S3 bucket that's both a CloudFront origin and publicly accessible. The correct pattern is to allow only CloudFront to access the bucket, forcing all traffic through the CDN where your WAF and other controls apply.

AWS introduced Origin Access Control (OAC) as the modern replacement for the older Origin Access Identity (OAI). OAC supports all S3 operations, Server Side Encryption with SSE-KMS, and cross-account origins:

resource "aws_cloudfront_origin_access_control" "main" {
  name                              = "s3-oac"
  origin_access_control_origin_type = "s3"
  signing_behavior                  = "always"
  signing_protocol                  = "sigv4"
}

resource "aws_s3_bucket_policy" "restrict_to_cloudfront" {
  bucket = aws_s3_bucket.origin.id
  policy = jsonencode({
    Statement = [{
      Effect    = "Allow"
      Principal = { Service = "cloudfront.amazonaws.com" }
      Action    = "s3:GetObject"
      Resource  = "${aws_s3_bucket.origin.arn}/*"
      Condition = {
        StringEquals = {
          "AWS:SourceArn" = aws_cloudfront_distribution.main.arn
        }
      }
    }]
  })
}

After configuring OAC, explicitly block public access on the S3 bucket. CloudFront handles all access; direct S3 access should be impossible. See our S3 security guide for the full S3 security model.

Preventing Origin Bypass

A subtle but critical vulnerability: if attackers know your ALB or EC2 origin's DNS name, they can bypass CloudFront entirely — and with it, your WAF rules, DDoS protection, and any CloudFront functions. The solution is to make your origin reject requests that don't come through CloudFront.

The most reliable method: configure your ALB to require a custom header that CloudFront adds to all requests:

resource "aws_cloudfront_distribution" "main" {
  origin {
    domain_name = aws_lb.app.dns_name
    custom_header {
      name  = "X-CloudFront-Secret"
      value = var.cloudfront_secret_header  # Store in Secrets Manager
    }
  }
}

Then configure your ALB listener rule to block requests without this header. Rotate the secret periodically. See our Secrets Manager guide for how to manage this secret.

Security Headers with CloudFront Response Headers Policies

CloudFront response headers policies let you add security headers to all responses without modifying your origin. This is the most efficient way to ensure consistent security header coverage:

resource "aws_cloudfront_response_headers_policy" "security" {
  name = "security-headers"

  security_headers_config {
    strict_transport_security {
      access_control_max_age_sec = 31536000
      include_subdomains         = true
      preload                    = true
      override                   = true
    }
    content_type_options {
      override = true
    }
    frame_options {
      frame_option = "DENY"
      override     = true
    }
    xss_protection {
      mode_block = true
      protection = true
      override   = true
    }
    referrer_policy {
      referrer_policy = "strict-origin-when-cross-origin"
      override        = true
    }
    content_security_policy {
      content_security_policy = "default-src 'self'; script-src 'self' https://cdn.example.com;"
      override                = true
    }
  }
}

The HSTS header with preload is particularly important — it tells browsers to never make insecure HTTP connections to your domain, even on the first visit.

Signed URLs and Signed Cookies for Private Content

For content that should only be accessible to authenticated users — downloadable files, video streams, member-only content — CloudFront signed URLs and cookies provide access control at the CDN layer.

When to Use Signed URLs vs. Signed Cookies

  • Signed URLs: Per-file access control. Use when each file needs individual authorization, or when your users don't accept cookies (API clients, for example).
  • Signed Cookies: Access to a pattern of URLs. Use when a user should have access to a set of files (a video library, a document collection) without generating individual signed URLs for each.

Both mechanisms use CloudFront key pairs (or Trusted Key Groups, the modern approach) to sign access tokens that expire after a configurable duration.

Geographic Restrictions

CloudFront geographic restrictions block or allow traffic based on the viewer's country, detected by IP geolocation. Use cases:

  • Compliance requirements restricting data to specific countries (GDPR, data residency)
  • Reducing attack surface from countries with high abuse rates
  • Licensing restrictions on content
resource "aws_cloudfront_distribution" "main" {
  restrictions {
    geo_restriction {
      restriction_type = "whitelist"
      locations        = ["US", "CA", "GB", "DE", "FR", "AU"]
    }
  }
}

Geo-restriction at the CloudFront level is processed before your origin receives the request, reducing load from blocked regions. Combine with WAF for more granular control at the application layer. See our WAF monitoring guide for integration patterns.

TLS Configuration and Certificate Management

CloudFront supports multiple security policy options that trade backward compatibility for security. For modern applications:

  • TLSv1.2_2021 — Requires TLS 1.2+, disables cipher suites with known weaknesses. Recommended for new applications.
  • TLSv1.2_2019 — Slightly more compatible, still secure.

Avoid TLSv1_2016 or older policies unless you have clients that specifically require older TLS versions — and audit those clients.

For certificates, use ACM in us-east-1 (the requirement for CloudFront distributions). Configure certificate renewal notifications so you're alerted 45 and 15 days before expiration. An expired CloudFront certificate causes immediate user-facing errors for everyone visiting your site.

CloudFront Access Logs

CloudFront access logs capture every request: viewer IP, request URL, response status, cache hit/miss, edge location, TLS version, and more. Enable logging to an S3 bucket:

resource "aws_cloudfront_distribution" "main" {
  logging_config {
    include_cookies = false
    bucket          = "${aws_s3_bucket.logs.bucket_domain_name}"
    prefix          = "cloudfront/"
  }
}

Query logs with Athena for security analysis. Useful queries:

  • Top IPs by request volume
  • Requests resulting in 4XX or 5XX errors
  • Edge locations being used (unexpected locations may indicate global scanning)
  • TLS version distribution (identify clients using old TLS)
  • Cache miss rate (high miss rate may indicate cache-busting attacks)

CloudFront Functions and Lambda@Edge for Security

CloudFront Functions run at the edge and can inspect and modify requests/responses with microsecond-level latency. Lambda@Edge is more powerful but higher latency. Security use cases:

CloudFront Functions

  • Redirect HTTP to HTTPS
  • Normalize request paths before caching
  • Add or modify security headers
  • Simple request validation (API key presence, header format)

Lambda@Edge

  • JWT validation at the edge (eliminates authentication latency from origin)
  • A/B testing with authenticated users
  • Complex request routing
  • Custom bot detection logic

Monitoring CloudFront Security Metrics

Configure CloudWatch alarms on CloudFront metrics:

  • 4xxErrorRate: Spike indicates scanning or misconfiguration
  • 5xxErrorRate: Origin failures — could indicate DoS against origin
  • TotalErrorRate: Overall health indicator
  • Requests: Spike in request volume for DDoS detection

For real-time monitoring, enable CloudFront real-time metrics (available in CloudWatch with an additional cost). Standard metrics have a 1-minute delay; real-time metrics have near-zero delay, useful for incident response.

Invalidations and Cache Poisoning

Cache poisoning — tricking CloudFront into caching a malicious response and serving it to other users — is a real attack vector. Mitigate it by:

  • Using cache keys that include all relevant request parameters
  • Not caching responses that include user-specific content
  • Setting appropriate Vary headers on responses
  • Never caching error responses (4xx, 5xx)

Monitor CloudTrail for unexpected CreateInvalidation calls — malicious actors sometimes invalidate the cache to force re-fetching of content they've manipulated at the origin. Our CloudTrail alerting guide covers how to set up these alerts.

FAQ

Do I need CloudFront if my users are all in one region?

Even for single-region deployments, CloudFront provides valuable security benefits: DDoS protection, WAF integration, TLS termination, and origin protection. The performance benefits are less relevant for single-region, but the security benefits remain.

How do I test if my origin is directly accessible?

Use a tool like curl to request your origin's hostname directly: curl -I https://your-alb-dns-name.region.elb.amazonaws.com/. If you get a response without the CloudFront secret header protection configured, your origin is accessible directly.

What's the difference between CloudFront WAF and ALB WAF?

CloudFront WAF runs at edge locations globally (us-east-1 WebACL). ALB WAF runs in the specific region where your ALB is deployed. For global protection, CloudFront WAF is generally better. For regional applications or those requiring VPC-aware WAF rules, ALB WAF may be appropriate. You can run both simultaneously for defense in depth.

Protect your AWS accounts before it's too late

Vigilare monitors your AWS accounts for suspension risks — billing anomalies, IAM issues, GuardDuty findings, and more — and alerts you before AWS takes action.

Written by Vigilare Engineering

Platform Team