7

My company's site has a static homepage for speed and cost reasons. We use S3 as the origin for CloudFront. Now, we would like to declare Strict-Transport-Security for the entire domain, but S3 seems to not send any headers we specify (beyond ones starting with like x-aws--). CloudFront doesn't seem to have any custom header option either.

Is this possible?

  • Not directly possible, though there are some conceivable workarounds... what benefit does HTTP STS give you, though, if the site is 100% static? Or are you wanting it on the "entire domain" for side effects... in the sense that a request directed to the main site will (?) also impose STS on all subdomains? – Michael - sqlbot Sep 22 '14 at 10:52
  • 1
    Michael While the homepage is static, our backend is not. It's on a subdomain. Yeah, that's the goal. – StackExchange User Sep 22 '14 at 11:42

3 Answers3

2

You can now add HTTP response headers natively in CloudFront (including HSTS), without modifying your origin or writing a function. Create a new response headers policy with your configuration, then attach the policy to one or more cache behaviors.

Documentation is available here: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/adding-response-headers.html

Cristian
  • 151
  • 2
  • Note that the SecurityHeadersConfig property should be used to configure HSTS, not the CustomHeadersConfig. – tschumann Apr 14 '22 at 07:14
1

David's answer points to the docs, which boil down to:

  1. Create a Lambda function like so. Note that Lambda@Edge has a limited set of runtimes and some additional constraints compared to other Lambda functions. For example, all functions must be created in us-east-1 - CloudFront will automagically replicate them to other regions - layers are not supported, and all triggers must use an explicit ARN - no aliases, or using $LATEST.
'use strict';
exports.handler = (event, context, callback) => {
  const response = event.Records[0].cf.response;
  const headers = response.headers;

  headers['strict-transport-security'] = [{
    key: 'Strict-Transport-Security',
    /* 
     * verify that max-age and 'includeSubdomains' are the settings you want
     */
    value: 'max-age=31536000; includeSubdomains; preload' 
  }];

  callback(null, response);
};
  1. Publish a version and deploy it to Lambda@Edge. You cannot use $LATEST or an alias for the next step.
  2. Associate the published function version with a CloudFront distribution. If this is a one-off task, it's probably easier to do it via the Lambda console. If you want to associate your function with multple distributions, it's probably easier to use the CloudFront console.
  3. You'll want to set the event type as origin-response (between S3 and the cache) or viewer-response (between cache and browser), and specify the ARN with the version you published above - e.g.

    arn:aws:lambda:us-east-1:1234567890:function:MY-FUNCTION-NAME:v1

  4. Wait for the distribution to update and test that the headers are present in the response

0

Starting 7/16/2017, the functionality you were looking for is available via Lambda@Edge, see http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-at-the-edge.html for general documentation, or a specific example at https://nvisium.com/blog/2017/08/10/lambda-edge-cloudfront-custom-headers/