DEV Community

Jurriaan Proos
Jurriaan Proos

Posted on • Originally published at jurriaan.cloud on

1

Improve your site’s security using Lambda@Edge

In this post I’ll show you how I improved my site’s security using Lambda@Edge.

I recently went through my list of bookmarks again and stumbled upon https://securityheaders.com/, a website that scans a URL and gives it a rating based on the security headers that are set in the response.

So I gave it a try with my personal website:

Bad result from securityheaders.com

Oops.

Let’s improve that.

In a previous post I already mentioned that I’m serving my blog using CloudFront and S3, which means I can easily add another Lambda@Edge function that add the required security headers to get this rating up.

The AWS documentation already gives quite a complete example on how to do this in Node.js, so I ported that to Python as that is what I use for the other Lambda@Edge function:

def handle_event(event, context):
    response = event["Records"][0]["cf"]["response"]
    headers = response["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": "no-referrer-when-downgrade"
    }]

    # If you remove the Server header in your code, CloudFront will still add its own header but it does not leak 
    # information about the backend server and does not give an attacker new information because they already know that 
    # they are connecting to a CloudFront IP address. <https://stackoverflow.com/a/58609507>
    if "server" in headers:
        del headers["server"]

    return response
Enter fullscreen mode Exit fullscreen mode

I then configured it to trigger on the origin-response event in my serverless.yaml (see the previous post for the rest of the serverless.yaml):

functions:
  originResponse:
    handler: src/functions/origin_response/handler.handle_event
    events:
      - cloudFront:
          eventType: origin-response
          origin: http://${self:custom.domainName}.s3-website-eu-west-1.amazonaws.com
Enter fullscreen mode Exit fullscreen mode

and deployed it.

After invalidating the cache I ran the check again:

Somewhat better result from securityheaders.com

Ok, getting somewhere!

I then fixed the error in the Strict-Transport-Security header (there’s a space in the value field in the example AWS gives) and added the following Permissions-Policy header.

headers["permissions-policy"] = [{
    "key": "Permissions-Policy",
    "value": "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), "
             "payment=(), usb=()"
}]
Enter fullscreen mode Exit fullscreen mode

Again invalidated the cache and ran the test again:

Best result from securityheaders.com

🎉

That’s it, in about 30 minutes I went from an F to an A+ rating!

The creator of https://securityheaders.com/ has written about all the headers above, so in case you’d like to learn more about those I suggest you check out these posts:

Other useful links

Image of Datadog

How to Diagram Your Cloud Architecture

Cloud architecture diagrams provide critical visibility into the resources in your environment and how they’re connected. In our latest eBook, AWS Solution Architects Jason Mimick and James Wenzel walk through best practices on how to build effective and professional diagrams.

Download the Free eBook

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay