Is it possible to set HSTS headers on an Amazon CloudFront distribution from a S3 origin?
5 Answers
An update on this...
HTTP response headers can now be customized via Lambda@edge functions. Please see http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-at-the-edge.html for the documentation. To try this, create a new lambda function in the AWS console. Choose 'Edge Nodge.js 4.3' for the language and look for the cloudfront-modify-response-header template. If you do this, Lambda will ask you which CloudFront distribution and event to apply the function to. Note that you can edit or change this at any time by going to the Cloudfront behavior tab.
Here's an example lambda function...
'use strict';
exports.handler = (event, context, callback) => {
const response = event.Records[0].cf.response;
response.headers['Strict-Transport-Security'] = 'max-age=2592000; includeSubDomains';
callback(null, response);
};
- 139
- 1
- 3
-
1Great, will try it out! – chrisvdb Apr 12 '17 at 01:54
-
I stumbled across the same article... did it work for you? @chrisvdb – Steverino May 25 '17 at 20:33
-
@Steverino Haven't actually come around to trying it, but as we're just setting up a second static website that could benefit from it we might try it out on this instance. I'll report back in that case, please do so too. Would be interesting to understand the performance impact as well. – chrisvdb May 26 '17 at 02:10
-
I gave it a try over the weekend... unfortunately it turns out that Lanbda@Edge is still in preview and hence I got some nondescript error about too many triggers (max = 0). I have now applied to get access via this [link](https://pages.awscloud.com/lambda-at-edge-preview.html). – chrisvdb May 29 '17 at 01:08
-
Success! The example code works as a charm... – chrisvdb Jun 07 '17 at 01:47
-
1Update - turns out that the 100 TPS limit in the current preview version of Lambda@Edge is not sufficient to reliably serve our (simple and low-traffic) website. Some assets randomly yield a 50x response code. – chrisvdb Jun 08 '17 at 01:53
-
Workaround: create a new behavior on CloudFront for "*.html" and/or "/" requests and attach the lambda trigger only to this behavior until Lambda@Edge increases the TPS limit. – chrisvdb Jun 10 '17 at 08:49
-
1The format of response.headers has changed. The above no longer works. – Hamish Moffatt Jul 26 '17 at 04:35
It is not currently possible, see https://forums.aws.amazon.com/thread.jspa?threadID=162252 for a discussion about it.
Edit: Lambda@Edge has made it possible, see below.
- 4,865
- 15
- 24
-
2AWS recently introduced Header Policies on CloudFront, which is a less tedious way to get this done. See: https://aws.amazon.com/blogs/networking-and-content-delivery/amazon-cloudfront-introduces-response-headers-policies/ – Kris Nov 08 '21 at 17:19
To add to Andrew's answer:
I have just tried this and a couple of notes: There is no longer specific edge nodejs runtime, but the lambda needs to be created in the N Virginia region and triggered by cloudfront origin-response or viewer-response.
The code out of the box doesnt seem to work any more. It gives ERR_CONTENT_DECODING_FAILED.
Solution is to use json syntax as follows:
response.headers['Strict-Transport-Security'] = [ { key: 'Strict-Transport-Security', value: "max-age=31536000; includeSubdomains; preload" } ];
response.headers['X-Content-Type-Options'] = [ { key: 'X-Content-Type-Options', value: "nosniff" } ];
- 51
- 1
- 1
-
More info on headers here: https://infosec.mozilla.org/guidelines/web_security – vhs Feb 19 '19 at 07:39
Another update on this...
You can now add custom HTTP response headers (including CORS and security headers like HSTS) natively in CloudFront—without modifying your origin or writing functions. If you go to Policies > Response headers in the console, you can create a reusable policy with your configuration then attach it to one or more cache behaviors where you would like those headers added. This is also available via the API, CLI, SDK, and so forth.
Documentation is available here: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/adding-response-headers.html
- 151
- 2
-
Note that the SecurityHeadersConfig property should be used to configure HSTS, not the CustomHeadersConfig. – tschumann Apr 14 '22 at 07:14
Correct, since Lambda@Edge is generally available they restricted it to N Virginia and one has to choose Node 6.10 rather than Node 4.3.
The relevant part of our code below (for our purpose this will always be a 302 permanent redirect):
'use strict';
exports.handler = (event, context, callback) => {
var request = event.Records[0].cf.request;
const response = {
status: '302',
statusDescription: '302 Found',
httpVersion: request.httpVersion,
headers: {
Location: [
{
"key":"Location",
"value":"someURL"
}
],
'Strict-Transport-Security': [
{
"key":"Strict-Transport-Security",
"value":'max-age=63072000; includeSubDomains; preload'
}
],
},
};
callback(null, response);
};
By configuring different behaviors on CloudFront you can limit which requests will call the Lambda function.
- 1,199
- 2
- 10
- 15