16

Is it possible to set HSTS headers on an Amazon CloudFront distribution from a S3 origin?

5 Answers 5

8

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.

1
13

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);
};
8
  • 1
    Great, will try it out!
    – chrisvdb
    Apr 12, 2017 at 1:54
  • I stumbled across the same article... did it work for you? @chrisvdb
    – Steverino
    May 25, 2017 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, 2017 at 2:10
  • 1
    Update - 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 8, 2017 at 1:53
  • 1
    The format of response.headers has changed. The above no longer works. Jul 26, 2017 at 4:35
5

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" } ];
1
3

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

1
  • Note that the SecurityHeadersConfig property should be used to configure HSTS, not the CustomHeadersConfig.
    – tschumann
    Apr 14, 2022 at 7:14
1

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
  • This was meant as response to Adam Maschek's post...
    – chrisvdb
    Jul 18, 2017 at 18:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .