Jahed Ahmed

Hardening Your CDN with HSTS

HTTPS is slowly becoming more and more common throughout the web, as it should. It provides a level of security and privacy that the web somehow neglected for decades. Decades worth of hyperlinks and caches have created a backlog of insecure HTTP destinations, regardless if the site itself now supports HTTPS.

Redirecting old HTTP traffic to HTTPS, while a good start to securing your website, still requires the initial insecure HTTP request to be made, which can be intercepted at any point in time.

This is where HTTP Strict Transport Security (HSTS) comes in. HSTS is a way to ensure your website is always loaded via HTTPS, without the need for constant insecure redirects.

I'll go through how to introduce HSTS to your website in a CDN configuration. Such a configuration has two points of insecure communication:

  1. The CDN to the Origin (e.g. Cloudflare to Your Web Server).
  2. The Client to the CDN (e.g. Web Browser to Cloudflare)

Important Prerequisites

Before continuing, you need to make sure your existing servers supports HTTPS for all of its content. Insecure HTTP requests will no longer work. Also, make sure you've streamlined your SSL certificate update processes so that you're not locked out of your website when the certificate expires.

Also, please read the entire post before doing anything as some steps are difficult to reverse if you come across any issues.

Securing CDN to Origin

The Origin can be any number of things. An AWS S3 bucket, a Virtual Private Server (VPS), etc. HSTS is just another HTTP header like any other and regardless of which service you're using, the same principals apply.

To make sure your website doesn't break, it's worth doing this gradually. HSTS headers have 3 parameters:

  1. How long the header is valid in seconds.
  2. If it should include subdomains.
  3. If it should preload.

To start, we can add the max-age header.

Strict-Transport-Security: max-age=300; includeSubDomains

This will make all requests cache your HSTS preference for 5 minutes (300 seconds). So if you publish this and remove it, any browsers that visited your website within those two points in time will carry on using HTTPS always for 5 minutes before asking again.

After you've added this header, you'll need to find some pages on your website that aren't already cached. Since we're securing the CDN to Origin network, we need to make sure the CDN can communicate with the Origin to refresh its caches.

Once your invalidated some caches, click around and make sure everything still works. Including any subdomains you own. You might want to wait a week and see if any new errors show up. How careful you are is up to you.

When you're happy with the results, you can bump up the max-age to whatever you want. I'd suggest a year, as we'll need it later on for the preload flag.

Strict-Transport-Security: max-age=31104000; includeSubDomains

Securing Client to CDN

Now that the Origin is secure, we can apply the same steps to the CDN. Add the same header with a small max-age, make sure the website still works using the same processes and when you're happy, bump up the max-age to a year.

HSTS Preload

Now that we've got HSTS up, we can consider switching on preload. Preloading essentially lets browsers know your website is strictly HTTPS without the user needing to make that initial request to ask; which itself can be an attack vector.

To add your site to this list of known websites, you can submit it using the HSTS Preload List Submission website. Make sure to follow their requirements. They also have general advice around HSTS.

At the end of these steps, your website will be operating fully under HTTPS with no insecure channels.

Thanks for reading.