AWS Lambda@Edge – support for custom headers in Amazon CloudFront

Sharing bucket content on Amazon S3 through CDNs (Content Delivery Network) such as CloudFlare, Amazon CloudFront, Akamai, etc. is a commonly used solution for people looking for a way to share content online.

4 minutes of reading

Modification of headers from AWS Lambda@Edge

When only using AWS solutions, you may face a specific obstacle, because CloudFront does not allow you to manipulate the content of http headers that pass through it. Manipulating headers can be crucial when you want to achieve one of the following examples:

  • Check cookies to rewrite URLs to different versions of the site for A/B testing.
  • Send different objects to users based on the User-Agent header, which contains information about the device that submitted the request. For example, you can send images in different resolutions to users based on their devices.
  • Check the headers or authorized tokens, insert the appropriate header, and allow access control before forwarding the request to the source.
  • Add, remove, and modify headers, and rewrite the URL path to direct users to different objects in the cache.

In this case, you can use another CDN provider or use an intermediary server, e.g. NGINX. However, in this situation, the use of ec2 instances deprives you of the main serverless advantage.

Are there other tools available that can help solve this problem?

AWS Lambda@Edge

Yes, it is possible to use AWS Lambda@Edge to solve this exact situation.

To put it simply, this involves creating a simple lambda function and then gluing it to the edge location of a CDN distribution to capture and manipulate headers in queries and responses.

When creating Lambda, it is important to remember several limitations that must be met in order to be able to use such a function to manipulate headers.

The first significant limitation is the list of technologies that can be used to create a function. It is limited to functions based on Python and JavaScript. Below is a list of currently supported versions.

  • Python 3.8
  • Related to Python 3.7:
  • Node.js 12
  • Node.js 10
  • Node.js 8 and Node.js 6 (support is available for already created functions based on these specific versions, the creation of new functions is not supported)

An example of function content that adds several headers to the returned response.

'use strict';
exports.handler = (event, context, callback) => {

//Get contents of response
const response = event.Records[0].cf.response;
const headers = response.headers;

//Set new headers
headers['strict-transport-security'] = [{key: 'Strict-Transport-Security', value: 'max-age= 63072000; includeSubdomains; preload'}];
headers['content-security-policy'] = [{key: 'Content-Security-Policy', value: "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'"}];
headers['x-content-type-options'] = [{key: 'X-Content-Type-Options', value: 'nosniff'}];
headers['x-frame-options'] = [{key: 'X-Frame-Options', value: 'DENY'}];
headers['x-xss-protection'] = [{key: 'X-XSS-Protection', value: '1; mode=block'}];
headers['referrer-policy'] = [{key: 'Referrer-Policy', value: 'same-origin'}];

//Return modified response
callback(null, response);
};

Another important requirement is the region in which the function is created, it is limited to N.Viriginia. After creating a function, remember to add the appropriate permissions necessary when using the function as a Lambda@Edge, namely, it is necessary to add “edgelambda.amazonaws.com” to the trusted policy that is assigned to our function.

Amazon CloudFront Setup

It is possible to join the function prepared in this way to the CloudFront distribution.

To do this, go to the Behaviors hostage in the CloudFront service management console, select the item you are interested in from the list and go to Edit. At the bottom of the page, you will find a place to add and configure the Lambda function. Now make sure to paste the ARN function along with its version number. Then choose the Event Type that suits your needs.

After approving the changes, you should wait until the function propagates between the edge locations where the CloudFront distribution works.

Summary

It can therefore be concluded that AWS Lambda@Edge is an ideal solution when there is a requirement to manipulate the content of headers. Especially when you do not want to mess around doing it on ordinary servers, which then have to be managed.

Comments