AWS CloudFront and S3: setting content security headers
How to configure content security headers correctly via AWS CloudFront and S3 to harden your web applications.
Content security headers are an important building block for hardening modern web applications. They protect against attacks like cross-site scripting (XSS), clickjacking and other injection attacks by telling the browser which resources are allowed to be loaded and executed.
The old way: a custom function
Until recently, the common approach with AWS CloudFront was to create a CloudFront Function that injected the desired security headers into every response. Such a function typically looks like this:
function handler(event) {
var response = event.response;
var headers = response.headers;
headers['cache-control'] = {value: 'public, max-age=86400'};
headers['content-security-policy'] = { value: "default-src 'self'; img-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; object-src 'none'; font-src 'self'; media-src 'self'; manifest-src 'self'"};
headers['permissions-policy'] = {value: 'accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()'};
return response;
}
This function then had to be added to the behavior settings of the CloudFront distribution under viewer response. It worked, but it was awkward to maintain and required coding skills.
The new way: response headers policy
Since May 2023 AWS CloudFront has offered a much simpler alternative: the response headers policy. It lets you configure security headers directly via the AWS console, with no custom code at all.
Step by step:
- Navigate to CloudFront > Policies > Response headers in the AWS console.
- Create a new policy with a meaningful name.
- Under Security headers, add the headers you want, for example
Content-Security-Policy,Strict-Transport-Security,X-Content-Type-OptionsandX-Frame-Options. - For headers like
Permissions-Policy, which aren't directly available as security headers, use the Custom headers section. - Edit your CloudFront distribution and, under Behavior > Response header policy, select the policy you just created.
- Run a cache invalidation so the new headers take effect immediately.
Conclusion
Setting content security headers is indispensable for any modern web application. While the old route via CloudFront Functions worked, the new response headers policy simplifies the process considerably. Configuration is now done comfortably through the console, is easier to maintain and no longer requires custom code. Anyone who wants to harden their CloudFront distribution should switch to the new method.