Securing GitHub pages with Terraform, CloudFront and Lambda

One of the common recurring requests for our team is the ability to host static web pages for small projects that don’t require a backend or lots of custom configuration. GitHub pages is the perfect place to host this sort of stuff as it’s reliable and lets the team keep the autonomy of updating their website, along with being low overhead and low cost for us. However, GitHub pages has two main issues:

  • No SSL on custom domains
  • No ability to change the headers sent by the server

I’ve written a Terraform module that can deploy everything needed to add a secure CloudFront distribution in front of any public-facing website in just a few lines:

This configuration stops a lot of smaller attack vectors, and takes us from an F score to a B- on the HTTP Observatory:

How it works
The module deploys an Amazon CloudFront CDN distribution that sits in front of the origin website, providing SSL via Amazon’s Certificate Manager. It additionally deploys a Amazon Lambda function that runs on each request, modifying the headers sent back to the viewer to add some headers recommended in the Web Security Guidelines. These are sane defaults for most static sites but in the future I’d like this module to be able to add any header with any value. The function is just a few lines of JS and executes in under 20ms, meaning costs are minimal.

We’ve now deployed this to six of our sites that are hosted on GitHub pages or Amazon S3, and hope it’s of use to anyone else who wants to add some security to their hosted pages. Thanks to @jclaudius and @kang who did pretty much all of the heavy lifting on the Lambda side, I just made it easier to deploy. The module is of course open-source and contributions are greatly appreciated:

9 Likes

As somebody who has taken advantage of it by hosting campaign websites on GitHub pages, congrats to everyone involved, great work!

1 Like

This is the Cloud Formation template we use on https://infosec.mozilla.org that the gist is from, in case you do not use Terraform.

Note that Terraform can associate Lambda@Edge functions with Cloud Front, while when we made this, Cloud Formation could not do it natively (ie not without writing an API call “as Cloud Formation function”).

Please also note that there are caveats here if you want to do something like this, but you have say multiple CNAMEs you want to point to the same dest repo. If you have just one, this shouldn’t be an issue (assuming you claim the VHOST using a CNAME file in the repo). However, if you have multiple CNAMEs, you can run into takeover issues at the GitHub layer and at the CloudFront layer. In which case, I believe a more appropriate solution would be to move hosting from GitHub and have some hook that pushes the origin to S3 and thus that eliminates the possibility for an attacker to claim your CNAMEs.

1 Like

Hi @jclaudius, thanks for the feedback.

Having some sort of automation for building s3 static websites from git repos would be ideal. That said, given the nature of the websites that we (ParSys) usually host in github (scrappy, non-dynamic and short-lived because they usually support a campaign) I think that by sticking to a single CNAME should be enough.

2 Likes

GitHub has since added support for HTTPS on custom domains back in May, so this is no longer necessary.

2 Likes