Skip to content
MDView as Markdown

AWS CloudFront

CloudFront can add a CSP header to responses without touching your origin, using a response headers policy attached to a cache behaviour. There is one trap worth knowing before you start.

The managed policy does not include CSP

CloudFront ships managed response headers policies, and one of them is called SecurityHeadersPolicy. It is easy to attach it, tick "security headers" off the list, and move on.

It does not include a Content Security Policy. SecurityHeadersPolicy sets exactly five headers:

  • Referrer-Policy: strict-origin-when-cross-origin
  • Strict-Transport-Security: max-age=31536000
  • X-Content-Type-Options: nosniff
  • X-Frame-Options: SAMEORIGIN
  • X-XSS-Protection: 1; mode=block

The same is true of CORS-and-SecurityHeadersPolicy and CORS-with-preflight-and-SecurityHeadersPolicy, which just combine that set with CORS headers. For a CSP you need a custom response headers policy.

What a custom policy gives you

  • A Content-Security-Policy header with the directives you specify.
  • An override flag controlling whether CloudFront replaces a Content-Security-Policy header already sent by the origin, or defers to it.
  • Attachment to one or more cache behaviours, so a policy can be scoped to a path pattern - your checkout, for example - rather than the whole distribution.
  • Management through the console, CloudFormation, the CLI or the SDKs.

Sending reports to Report URI

Create a custom response headers policy and put your reporting directives in the header value. Your URLs come from the Setup page:

default-src 'none'; script-src 'report-sha256'; form-action 'none'; frame-ancestors 'none'; report-uri https://abc123.report-uri.com/r/d/csp/wizard; report-to wizard

report-to sends reports through the Reporting API, so add these two as custom headers in the same policy:

Reporting-Endpoints: default="https://abc123.report-uri.com/a/d/g", wizard="https://abc123.report-uri.com/a/d/g/wizard"
Report-To: {"group":"default","max_age":31536000,"endpoints":[{"url":"https://abc123.report-uri.com/a/d/g"}],"include_subdomains":true},{"group":"wizard","max_age":31536000,"endpoints":[{"url":"https://abc123.report-uri.com/a/d/g/wizard"}],"include_subdomains":true}

'report-sha256' in script-src turns on CSP Integrity, which reports a hash of every script that loads.

That is the same starting policy we recommend for the CSP Wizard. Note that CloudFront's response headers policy has a dedicated field for Content-Security-Policy - to run a report-only rollout you will need to add Content-Security-Policy-Report-Only as a custom header instead.

Things to watch for

  • Decide deliberately whether to override the origin. Leaving override off when the origin also sends a policy means the browser gets two, and enforces the intersection of both.
  • CloudFront caches responses along with their headers. After changing a policy, invalidate rather than waiting to see whether the new one is live.
  • A response headers policy is static, so it cannot generate a per-request nonce. Nonce-based policies have to come from the application - see our Frameworks guides.

Official documentation

AWS - Create response headers policies

Start Monitoring with Report URI

Already using us for CSP? Find your CSP reporting directives on Setup, or view your CSP reports.

New to Report URI? Create an account and grab your CSP reporting directives from the Setup page.

Start your free trial