CloudFront distribution without strict security headers policy

ID

cloudfront_security_headers_policy

Severity

high

Vendor

AWS

Resource

CloudFront

Tags

reachable

Description

AWS CloudFront (CF) could have HTTP Security headers configured, which improve the privacy and security of a web application and protect it from vulnerabilities at the client side.

The most common HTTP security headers are:

AWS provides a set of managed response headers policies, possibly less strict that the configured by this detector.

This detector checks that each aws_cloudfront_distribution resource has a matching aws_cloudfront_response_headers_policy with the security_headers_config block matching the expected configured policy.

The detector will report a flaw if the CF does not have a matching response headers policy, or if any of the headers configured do not match the expected values.

Further details on the Terraform configuration: aws_cloudfront_response_headers_policy.

Examples

resource "aws_cloudfront_distribution" "my_cdn" { (1)
  enabled = true
}
1 No response headers policy, this is considered a flaw.

Mitigation / Fix

Buildtime

Terraform

Add a aws_cloudfront_response_headers_policy resource configured with the expected values for the HTTP response security headers:

resource "aws_cloudfront_distribution" "my_cdn" {
  enabled = true

  default_cache_behavior {
    // register a response_headers_policy
    response_headers_policy_id = aws_cloudfront_response_headers_policy.strict.id
  }
}

// Strict policy conforming with the desired security level
resource "aws_cloudfront_response_headers_policy" "strict" {
  name    = "strict-policy"

  security_headers_config {
    content_security_policy {
      content_security_policy = "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'; frame-ancestors 'none'"
      override = true
    }
    content_type_options {
      override = true
    }
    frame_options {
      frame_option = "DENY"
      override = true
    }
    referrer_policy {
      referrer_policy = "same-origin"
      override = true
    }
    strict_transport_security {
      access_control_max_age_sec = 31536000
      include_subdomains         = true
      override                   = true
      preload                    = true
    }
    xss_protection {
      mode_block = true
      override   = true
      protection = true
    }
  }
}

Configuration

You may configure the policy to enforce by editing the properties entry in cloudfront_security_headers_policy.yml file:

properties:
# Defines the security headers that should be configured
# Comment entries that should not be enforced

  # Content-Security-Policy
  content_security_policy:
    override: true
    content_security_policy: "default-src 'none'"
  # X-Content-Type-Options
  content_type_options:
    override: true
  # X-Frame-Options
  frame_options:
    override: true
    frame_option: "DENY"
  # Referrer-Policy
  referrer_policy:
    referrer_policy: "same-origin"
    override: true
  # Strict-Transport-Security
  strict_transport_security:
    override: true
    access_control_max_age_sec: 31536000 # 1 year
    include_subdomains: true
    preload: true
  # X-XSS-Protection
  xss_protection:
    mode_block: true
    protection: true
A too strict policy for security headers may cause failures with certain web applications; a good balance between security and functionality requires to understand the effect that a looser policy allowing an application to work could have on application security.

You may use a less strict policy if needed, like this:

  # Content-Security-Policy
  content_security_policy:
    content_security_policy: "default-src 'self'"
  # X-Frame-Options
  frame_options:
    frame_option: "SAMEORIGIN"
  # Referrer-Policy
  referrer_policy:
    referrer_policy: "strict-origin-when-cross-origin"
  # Strict-Transport-Security
  strict_transport_security:
    access_control_max_age_sec: 31536000 # 1 year
    include_subdomains: true
    preload: true
  # X-XSS-Protection
  xss_protection:
    mode_block: true
    protection: true