Skip to content
  • Services
    • Strategy
    • Customer Experience
    • Agile Delivery
    • Security
  • About
  • Partners
    • Aha!
    • Amazon Web Services (AWS)
    • Atlassian
    • Cloudflare
    • GitHub
    • InVision
    • Ionic
    • Pendo
    • Radar
    • Vue.js
  • Work
    • Modus Create Labs
  • Insights
    • Blog
  • Careers
  • Contact
  • Services
    • Strategy
    • Customer Experience
    • Agile Delivery
    • Security
  • About
  • Partners
    • Aha!
    • Amazon Web Services (AWS)
    • Atlassian
    • Cloudflare
    • GitHub
    • InVision
    • Ionic
    • Pendo
    • Radar
    • Vue.js
  • Work
    • Modus Create Labs
  • Insights
    • Blog
  • Careers
  • Contact
February 20, 2020

5 Simple Ways to Improve Security with Lambda at Edge

AWS, DevOps, JavaScript, Security, Serverless

Lambda@Edge is Amazon Web Services’s (AWS’s) Lambda service run on the Amazon CloudFront Global Edge Network. You can utilize this service to run code in a serverless fashion at a location that is close to the end user.

There are numerous measures you can take to improve security with Lambda@Edge. Today we are going to cover five ways via the use of security headers. Lambda@Edge provides you with the ability to customize headers after responses have left the origin.

X-XSS-Protection

The X-XSS-Protection header helps prevent a number of cross-site scripting (XSS) attacks in a handful of browsers. Mozilla notes:

X-XSS-Protection is a feature of Internet Explorer and Chrome that stops pages from loading when they detect reflected cross-site scripting (XSS) attacks. Although these protections are largely unnecessary in modern browsers when sites implement a strong Content Security Policy that disables the use of inline JavaScript (‘unsafe-inline’), they can still provide protections for users of older web browsers that don’t yet support CSP.

Directions

  1. Create a Lambda function with the following code:
exports.handler = (event, context, callback) => {
  const { response } = event.Records[0].cf;

  response.headers["x-xss-protection"] = [{ value: "1; mode=block" }];

  return callback(null, response);
};
  1. Set the Lambda function to run as the CloudFront origin response or viewer response

X-Content-Type-Options

The X-Content-Type-Options header helps prevent MIME type related XSS attacks. Mozilla notes:

X-Content-Type-Options is a header supported by Internet Explorer, Chrome and Firefox 50+ that tells it not to load scripts and stylesheets unless the server indicates the correct MIME type. Without this header, these browsers can incorrectly detect files as scripts and stylesheets, leading to XSS attacks. As such, all sites must set the X-Content-Type-Options header and the appropriate MIME types for files that they serve.

Directions

  1. Create a Lambda function with the following code:
exports.handler = (event, context, callback) => {
  const { response } = event.Records[0].cf;

  response.headers["x-content-type-options"] = [{ value: "nosniff" }];

  return callback(null, response);
};
  1. Set the Lambda function to run as the CloudFront origin response or viewer response

X-Frame-Options

The X-Frame-Options header helps prevent frame related XSS attacks. Mozilla notes:

X-Frame-Options is an HTTP header that allows sites control over how your site may be framed within an iframe. Clickjacking is a practical attack that allows malicious sites to trick users into clicking links on your site even though they may appear to not be on your site at all. As such, the use of the X-Frame-Options header is mandatory for all new websites, and all existing websites are expected to add support for X-Frame-Options as soon as possible.

Directions

  1. Create a Lambda function with the following code:
exports.handler = (event, context, callback) => {
  const { response } = event.Records[0].cf;

  response.headers["x-frame-options"] = [{ value: "DENY" }];

  return callback(null, response);
};
  1. Set the Lambda function to run as the CloudFront origin response or viewer response

Content-Security-Policy

The Content-Security-Policy header helps prevent the vast majority of XSS attacks. Mozilla notes:

Content Security Policy (CSP) is an HTTP header that allows site operators fine-grained control over where resources on their site can be loaded from. The use of this header is the best method to prevent cross-site scripting (XSS) vulnerabilities. Due to the difficulty in retrofitting CSP into existing websites, CSP is mandatory for all new websites and is strongly recommended for all existing high-risk sites.

One of the main benefits of the CSP comes from the disabling of inline Javascript. New websites can be built with this in mind, but fixing all of the inline Javascript on older websites may not be an option. As such, exercise caution when adding a CSP to existing websites.

Directions

  1. Create a Lambda function with the following code:
exports.handler = (event, context, callback) => {
  const { response } = event.Records[0].cf;

  response.headers["content-security-policy"] = [
    {
      value:
        "default-src 'self'; object-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'; block-all-mixed-content",
    },
  ];

  return callback(null, response);
};
  1. Set the Lambda function to run as the CloudFront origin response or viewer response

Gotchas

One challenge that single page applications (SPAs) face if they implement server side rendering (SSR) is with inlining critical styles to the document head and inlining application state to the document body. To successfully resolve this challenge, you will need to calculate hashes for the script(s) and style(s) and put base64 encoded versions in the script-src and style-src sections of the content security policy. For example:

script-src 'self' 'sha256-1LWiqTBX9ooah9yxrjAPIapj/bpKu8E2gxHrAcrvXJQ='; style-src 'self' 'sha256-lEmNQfaoD6+gZL66vjr9syPi0uIaBbN/95dTug2Tb1g=';

Strict-Transport-Security

The Strict-Transport-Security header prevents insecure access to your website. Mozilla notes:

HTTP Strict Transport Security (HSTS) is an HTTP header that notifies user agents to only connect to a given site over HTTPS, even if the scheme chosen was HTTP. Browsers that have had HSTS set for a given site will transparently upgrade all requests to HTTPS. HSTS also tells the browser to treat TLS and certificate-related errors more strictly by disabling the ability for users to bypass the error page.

Directions

  1. Create a Lambda function with the following code:
exports.handler = (event, context, callback) => {
  const { response } = event.Records[0].cf;

  response.headers["strict-transport-security"] = [
    { value: "max-age=31536000; includeSubDomains" },
  ];

  return callback(null, response);
};
  1. Set the Lambda function to run as the CloudFront origin response or viewer response

Extra Credit

If you are confident that all apex, subdomains, and nested subdomains of your domain will be served securely, you can submit your domain to be included on the HSTS preload list.

Putting It All Together

Rather than creating five separate Lambda@Edge functions, you can combine them all into one function.

Directions

  1. Create a Lambda function with the following code:
exports.handler = (event, context, callback) => {
  const { response } = event.Records[0].cf;

  response.headers["x-xss-protection"] = [{ value: "1; mode=block" }];
  response.headers["x-content-type-options"] = [{ value: "nosniff" }];
  response.headers["x-frame-options"] = [{ value: "DENY" }];
  response.headers["content-security-policy"] = [
    {
      value:
        "default-src 'self'; object-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'; block-all-mixed-content",
    },
  ];
  response.headers["strict-transport-security"] = [
    { value: "max-age=31536000; includeSubDomains" },
  ];

  return callback(null, response);
};
  1. Set the Lambda function to run as the CloudFront origin response or viewer response

Testing the Results

Mozilla has created a great tool for testing the presence and validity of the aforementioned security headers on your website. You must perform the following steps:

  1. Visit the Mozilla Observatory tool in your browser
  2. Type the domain name of your website (E.g.: www.example.com)
  3. Click the Scan Me button

In Summary

Security should be one of the top concerns when operating any web application. Fortunately, Lambda@Edge makes it easy to implement best security practices across the board on your websites. I challenge you to incorporate all of the aforementioned headers on all of your web applications and strive for an A on the Mozilla Observatory tool.

Posted in AWS, DevOps, JavaScript, Security, Serverless
Share this

Lucas Still

Lucas Still is a software architect at Modus Create. As a serverless evangelist and full stack wizard, Lucas spends his days converting technical dreams into digital reality. He is a certified AWS solutions architect professional, Vue enthusiast, TypeScript fan and RDBMS buff. Lucas is a family man living in the state for lovers in USA. When not coding, you’ll likely find him playing with his kids, DIY'ing his house or traveling around the country.
Follow

Related Posts

  • 9 Ways Agile Developers Can Improve Their Scrum Skills
    9 Ways Agile Developers Can Improve Their Scrum Skills

    With more than 10 years of experience in Scrum and Scrum-like teams, I finally decided…

  • 9 Ways Agile Developers Can Improve Their Scrum Skills
    9 Ways Agile Developers Can Improve Their Scrum Skills

    With more than 10 years of experience in Scrum and Scrum-like teams, I finally decided…

Subscribe to the Modus Newsletter

Receive the latest blog articles and insights every month from the Modus team.

Join Our Global Team

Would you like to be a Modite? We are redefining distributed consultative services. We have open positions throughout the globe.

See Open Positions

Let's Chat

If forms aren’t your thing, you can always call us (+1-855-721-7223).

Modus-Logo-Primary-White.svg
  • Services
  • About
  • Partners
  • Work
  • Insights
  • Newsroom
  • Careers
  • Contact
Virginia (US)

12100 Sunset Hills Road
Suite 150
Reston, Virginia, 20190
Tel: +1-855-721-7223

California (US)
12130 Millennium Dr

Los Angeles, CA 90094

Missouri (US)
609 E High St

Jefferson City, MO 65101

Romania

Str. Mihai Veliciu, no. 17
Cluj-Napoca, Romania
Tel: +40-0786-887-444

Costa Rica

2nd Floor, Plaza Koros, Av 3
San José, Santa Ana, Costa Rica

© 2021 Modus. All Rights Reserved.

Privacy Policy | Accessibility Statement | Sitemap

This website uses cookies.
These cookies are used to collect information about how you interact with our website and allow us to remember you. We use this information in order to improve and customize your browsing experience, and for analytics and metrics about our visitors both on this website and other media. To find out more about the cookies we use, see our Privacy Policy.

Accept
Privacy & Cookies Policy

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these cookies, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may have an effect on your browsing experience.
Necessary
Always Enabled

Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.

Non-necessary

Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.

Scroll To Top