10

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

7

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.

10

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);
};
  • 1
    Great, will try it out! – chrisvdb Apr 12 '17 at 1: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 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 '17 at 1:53
  • 1
    The format of response.headers has changed. The above no longer works. – Hamish Moffatt Jul 26 '17 at 4:35
4

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

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.

  • This was meant as response to Adam Maschek's post... – chrisvdb Jul 18 '17 at 18:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.