UPDATE: AWS announced over the weekend that they're enhancing protections against this kind of scenario.
A few weeks ago a security researcher shared it was possible to hijack domains that were misconfigured in Amazon CloudFront, Amazon's CDN-as-a-service.
Being able to hijack a misconfigured domain is somewhat terrifying. While I've used CloudFront extensively, I was surprised by this behaviour and wanted to explore it a bit more. As you'll see below, the routing of a request to CloudFront is managed differently from the processing of a request...
It's worth noting that the the default configuration for CloudFront is secure. The issue can only arise when additional DNS configuration is used and CloudFront settings are not kept in sync, which is unfortunately not very hard to do.
The Issue
In this example setup domainA.com
is configured correctly, and will work as expected.
The domain domainA.com
is pointing to the CloudFront generated domain name d1.cloudfront.net
. domainA.com
is in the CNAME configuration for the distribution, so everything is fine.
In the following setup you might think that sub.domainA.com
would be served up the same content as domainA.com
by the CloudFront distribution Distribution 1
, due to the way DNS is configured.
Unfortunately that's not the case, and when the setup (of DNS and CloudFront) are out of sync like this a form of hijacking can happen.
In order to serve traffic for all the various origins, CloudFront has to process the request to route it to the right distribution. This is implemented by checking the Host
HTTP header to route the incoming request to the appropriate distribution. The Host
header must be sent in all HTTP requests (as called out in the MDN docs), so depending on it is not unusual (in fact, it's required to run a CDN).
The routing requirement is that the domain points to CloudFront, but CloudFront doesn't look at the DNS setup when it processes the request. An administrator thinks they've configured things correctly because the DNS for the subdomain is pointing to CloudFront, but without the corresponding entry that matches the Host
header in the distribution setup the request won't be processed as intended.
The key thing to note is that Distribution 2
doesn't need to be owned or operated by the owener of Distribution 1
. Hence, the ability to hijack the domain.
The Impact
These days, being able to execute JavaScript on a trusted domain is no small deal. While CORS blocks requests from other domains (including subdomains) by default, I can easily imagine scenarios where servers have been configured to trust subdomains within a supposedly trusted domain hierarchy. The impact in this scenario would be huge.
Large organisations could easily have different teams managing the DNS and CloudFront configurations, which would lend itself to this misconfiguration happening (and it did, just check the names mentioned in the original article).
Another, more subtle attack for domain hijacking these days is phishing. Being able to set up a legit-looking website on a trusted domain would be much harder to catch-out than the usual lame phishing attempts involving domains that look nothing like the originals.
The Fix
Thankfully, the fix is an easy one.
To prevent this ever being an issue for you domains, simply add a wildcard entry (e.g. *.domainA.com
) to your CloudFront distribution so that any and all subdomain requests - no matter how they are configured - will be routed to your distribution.
Specifically, include the wildcard in the "Alternate Domain Names (CNAMEs)" configuration field of the CloudFront distribution:
This should become part of everyone's default approach to CloudFront configuration. In all but the most complicated setups, it will save you trouble later on. At the very least it will save you some worry.
Full credit to Matt Westfall (@disloops) for his great write up and proper disclosure to the relevant parties before going public.