I was doing some work on securityheaders.io the other day and I noticed something about the CDN that I use for some of my assets. They didn't use HSTS to enforce the use of HTTPS in compliant user agents, which I thought was a little odd.
HTTP Strict Transport Security
HSTS is simply a setting that a website can set that tells a browser to always use HTTPS. If an attacker is trying to launch an attack and force us to use HTTP, the browser will know to only use HTTPS and can avoid being compromised. We don't want to use HTTP as it's an insecure protocol that allows people to meddle with our traffic, this is why HTTPS+HSTS is essential! You can read more about HSTS in my article HSTS - The missing link in Transport Layer Security.
Why would a CDN not use HSTS?
I don't know. I noticed that assets I use from cdnjs.cloudlfare.com did not have a HSTS header set. I thought this was a little odd really, why would you not want to protect CDN traffic and ensure that capable clients always use HTTPS? Here are the securityheaders.io results for an asset hosted on the CDN:
At first glance it might look bad that they're getting an F here, but it's mostly expected and perfectly reasonable. They don't need a CSP here, I can understand them not using HPKP, XFO isn't required, XXSSP wouldn't be much use and maybe they could use XCTO. The biggest thing that I can't understand here is why there is no HSTS, the Strict-Transport-Security header isn't being sent and the connection is secure, we're using HTTPS.
HSTS preloading to the rescue?
The only other thing I could think of is that they could be using HSTS Preloading. In essence, HSTS Preloading allows a site to be built in to the browser, into the actual source code, and marked as being a HSTS host without having to set the header on every response. Putting my CDN hat on this seems like it could be a performance decision to avoid having to add the HSTS header to every single asset they serve from the CDN, but it wasn't the case. You can take a look at the sites that are in the Chromium HSTS Preload List, and by extension Chrome, Opera, Firefox, Safari and Edge, and you will see that their domain is not present. The cdnjs.com domain is in the list, with includeSubDomains set, but this doesn't cover the CDN hosted assets.
The cloudflare.com domain is also preloaded but they don't have the includeSubDomains flag set and the specific cdnjs.cloudflare.com subdomain we're looking at is not included.
This means that the CDN hosted assets are not covered by a preloaded HSTS policy either, so there is no HSTS protection at all. This got me wondering, do other CDNs use HSTS?
Other CDN providers
I decided to look at a few of the other big CDN providers out there and see if they were using HSTS to provide additional protection to CDN hosted assets.
The Google CDN does set the XCTO header alongside XXSSP but there was no HSTS header on the response.
Fortunately, Google do have their CDN HSTS preloaded and they're also preloaded for HPKP too!
Because the includeSubDomains flag is set on the googleapis.com preload, their CDN domain ajax.googleapis.com will benefit from the HSTS and HPKP preload entry. This means they don't need to issue the HSTS header on every response but all HSTS compliant user agents that include the preload list get full protection, which is pretty much all mainstream browsers.
Next up was Microsoft and their results were the first that I saw with the HSTS header set!
Not only that, but the header was set with a very nice max-age value of 1 year!
Unfortunately they do not have their CDN in the HSTS preload list, so perhaps an awesome next step for them would be to get it submitted given they have a really high max-age in their policy.
Another free and open source CDN, jsDelivr are kind enough to host assets for you but sadly don't deliver a HSTS header with them.
Their domain is also not in the HSTS preload list, so no protection is offered to compliant user agents.
Given that we're checking the latest version of jQuery, I figured I'd check the jQuery CDN itself.
Unfortunately there is no HSTS header set and they also don't appear in the HSTS preload list. Another CDN without either protection.
Last up was the BootstrapCDN provided by MaxCDN. They also do not set a HSTS header on responses with assets.
To close it off I couldn't find a HSTS preload entry for them either.
Protecting huge amounts of traffic
The above CDN providers probably account for a considerable sum of traffic between them. This is all traffic that could be encrypted with the assurance and protection offered by HSTS, enforced by the CDN and requires zero interaction with, or burden on, the sites using the CDN. These CDNs do not redirect traffic from HTTP to HTTPS, with valid reasons, but legacy code and references that were added a long time ago could still be resulting in insecure connections. A HSTS preload entry seems like the easiest and most obvious win here.
- There is no overhead on serving assets by adding a HSTS header.
- Clients loading these assets over HTTP, but are HSTS/preload compliant, will get protection.
- Clients that are HSTS compliant and have the preload list can obviously support HTTPS.
- The CDN can serve over HTTPS as they already do so, it just isn't enforced.
I will keep the article updated with any changes to the above CDNs but if I miss anything, please drop me a comment below!
On the topic of CDNs and security, Subresource Integrity allows us to be sure that assets served by a CDN aren't tampered with. You can read more in Subresource Intergrity: Securing CDN Loaded Assets and it's really simple and easy to setup, check it out!