Published on

Adding HTTP Security Headers Using Lambda@Edge and Amazon CloudFront

Authors
  • avatar
    Name
    Sneha Tuladhar
    Linkedin
    @

Table of Contents


Introduction

Security headers are HTTP response headers that tell your browser how to handle your site’s content. For example, the X-XSS-Protection header helps prevent cross-site scripting (XSS) attacks by blocking pages if suspicious scripts are detected. It works in browsers like Internet Explorer and Chrome.

Protection against cross-site scripting (XSS), clickjacking, and data injection attacks is made easy with HTTP security headers. Security headers have been attached to the CloudFront distribution through Lambda@Edge to enhance protection.

CloudFront either caches content from the server or pulls it from S3 if not cached. Lambda@Edge allows modifications to headers before data is sent to users, improving security and reducing latency.

triggering lambda edge functions

Prerequisites

  • An Amazon S3 bucket hosting your website.
  • A CloudFront distribution configured to serve content from the S3 bucket.
  • AWS Lambda access with permissions to create functions.

Steps to Add Security Headers

1. Create a Lambda Function

  1. Open the AWS Lambda Console in US East (N. Virginia) - us-east-1.
  2. Click Create function.
  3. Select Use a blueprint.
  4. Enter a function name and select Node.js 16.x as the runtime.
  5. Under Permissions, choose Create a new role with basic Lambda permissions.
  6. Click Create function.
triggering lambda edge functions

2. Add Security Headers Code

Scroll to the Code Source section and replace index.js with:

'use strict';
export const handler = async (event) => {
    // 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
    return response;
};

3. Deploy and Test

-1.Click the Test tab. -2.Click Create new test event. -3.Enter an Event Name and modify it. Here’s a sample test event you can use in the AWS Lambda console: Terraform snippet:

{
  "Records": [
    {
      "cf": {
        "config": {
          "distributionId": "EXAMPLE123"
        },
        "request": {
          "uri": "/index.html",
          "method": "GET",
          "headers": {
            "host": [
              {
                "key": "Host",
                "value": "example.cloudfront.net"
              }
            ]
          }
        },
        "response": {
          "status": "200",
          "statusDescription": "OK",
          "headers": {
            "cache-control": [
              {
                "key": "Cache-Control",
                "value": "max-age=100"
              }
            ],
            "content-type": [
              {
                "key": "Content-Type",
                "value": "text/html"
              }
            ]
          }
        }
      }
    }
  ]
}
  1. Click Create and then Test to execute the function.
  2. Check the Execution result section to see the output and logs.
Test event for function

4. Configure CloudFront Trigger

  1. Navigate to the Lambda function you created.
  2. Click Add trigger → Choose CloudFront.
:Adding lambda trigger
  1. Select the CloudFront distribution serving your website.
  2. Set Cache Behavior to *.
  3. Choose Origin Response as the event.
  4. Enable Replicate across regions.
  5. Click Add.
Deploying to lambda edge

5. Deploy and Verify

  • Wait for CloudFront to deploy the updated configuration (~2–7 minutes).
  • Open your website in a browser.
  • Open Developer Tools → Network Tab.
  • Reload the page and inspect the response headers.
Responde headers

6. Test Security Headers


Monitoring and Debugging

  • Check Amazon CloudWatch Logs for Lambda function execution details.
  • Verify CloudFront distribution status (should be Deployed).
  • Ensure Lambda executes on Origin Response events.
  • Debug Content Security Policy (CSP) issues by inspecting blocked requests in browser Developer Tools.
  • Modify the Content-Security-Policy header as needed to allow necessary resources while maintaining security.
  • Clear CloudFront Cache (Invalidate) when required.
cache invalidations

💡 Note: Invalidating everything (/*) can be expensive if done frequently. Target only specific changed files when possible.


Conclusion

By configuring AWS Lambda@Edge to inject HTTP security headers:

  • You have strengthened your website’s defenses against various online threats.
  • Security headers protect user data and maintain a secure browsing environment.
  • Regularly monitor CloudWatch logs and review security header performance using tools like Mozilla Observatory.
  • Manage your CloudFront cache efficiently to ensure updates take effect.

With these security measures in place, your website is more secure and reliable for users.