TL;DR, AWS did not perform any conflict check between regular domains and trailing dot domains. Some browsers hide the URL completely using Extended Validation (EV) SSL. Combined, these issues created some interesting attack vectors.
When it comes to Amazon Web Services (AWS), both S3 and CloudFront lack domain validation. If a domain has a DNS entry pointing to either S3 or CloudFront but the domain is not actually claimed in S3 or CloudFront, it’s possible for anyone to claim the domain and serve their own content on the domain using these two AWS services. Below, we will explain another problem with the lack of domain verification, combining trailing dot domains, conflict checks and how SSL common name matching works today.
AWS CloudFront is a Content Delivery Network (CDN) service, provided by Amazon Web Services, with a bunch of features. By uploading a SSL-certificate and private keys to your CloudFront distribution, CloudFront can also work as a SSL-proxy. This means that CloudFront will provide your SSL-certificate as soon as someone requests your domain through CloudFront.
Proof of Concept setup
In our example below, we simulate
www.example.com being setup to use CloudFront:
$ host www.example.com www.example.com is an alias for dsq4yj3n99jjk.cloudfront.net. dsq4yj3n99jjk.cloudfront.net has address 126.96.36.199 dsq4yj3n99jjk.cloudfront.net has address 188.8.131.52 dsq4yj3n99jjk.cloudfront.net has address 184.108.40.206
It also has an EV-SSL-certificate uploaded to CloudFront to be able to serve the content using SSL:
$ openssl s_client -connect www.example.com:443 -tls1 -servername www.example.com | openssl x509 -noout -text ... Issuer: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 EV SSL CA - G3 ... X509v3 Subject Alternative Name: DNS:www.example.com
These two criteria enable the attack below.
When doing research on domain validation, we noticed that CloudFront had some restrictions when trying to claim a domain as an “Alternate Domain Name”:
Now, this turned out to be a client-side only validation. By intercepting the request and modifying the content to add the domain with a trailing dot instead, the request went through and was validated:
If you don’t know about a trailing dot domain, it is actually a fully qualified domain name (FQDN) and represented as is in DNS, the dot meaning the root label. Unfortunately, it’s very common that cloud providers do not recognize this, especially when it comes to domain conflict checks. In the case of CloudFront, this meant that even if
www.example.com was taken and was being used, AWS still thought
www.example.com. wasn’t taken.
This turned out to be really bad.
First, since CloudFront can act as a proxy, you were able to pick your own origin for this trailing dot domain. The origin you used would then turn up on
www.example.com.. Second, CloudFront has some interesting logging settings which make it possible to see all requests being sent through this trailing dot domain:
Also, there is another setting:
Yes please. This means that all cookies passed through the trailing dot domain will be logged to the configured logging-bucket.
Now, the modern browser SOP (Same-Origin Policy) is actually really strict when it comes to trailing dot domains.
www.example.com is not the same domain as
www.example.com.. Thus, browsers will not send cookies set on the regular domain to the trailing dot domain.
However, by setting the origin of our distribution to the regular page, we could now Man-in-the-Middle (MITM) the connection if anyone used the trailing dot domain. As an aside, when we looked at our logs for the domains which we tested this on, we noticed that we had a bunch of referer-headers sent from Yahoo Mail. Testing it out, we found that Yahoo Mail will actually link to the trailing dot domain if a domain name ends a sentence:
This was now sending real users to the domains we were testing this on.
The worst problem here is how SSL works, and most importantly – EV-SSL. Let’s do a little chart:
* Cloud: ❌ FQDN=different! Conflict check bypassed! * SOP: ❌ FQDN=different! No access! No cookies! * EV-SSL: ✅ FQDN=same! Provide valid cert! Show green bar!
This gets a little bit dramatic when some of the browsers decide that:
Oh, well, they have a EV-SSL, let’s remove the domain completely and replace it with the company name from the cert.
Here’s an example with a PayPal domain and EV-SSL providing content from
www.example.com on the trailing dot domain:
How can you tell that this domain is not actually PayPal? In this case, there’s no way, no way at all, to tell that this is not actually PayPal. The only reason why the SSL is actually valid for the trailing dot domain, is because of a discussion on Mozilla’s bug tracker from September 2014:
Yes, it’s ok to match “www.example.com.” (trailing) to the cert with “www.example.com” (no trailing)
It’s also OK to match “www.example.com” (no trailing) to the cert with “www.example.com.” (trailing)
We’ve talked about subdomain takeovers before, but this creates another attack scenario for the same issue. Additionally, many cloud providers other than AWS are currently vulnerable. If you are a cloud provider, please make sure you are not allowing trailing dot domains at all, or that your conflict check properly handles this case.
In regards to domain validation, S3 has similar issues. In the example above we were able to claim a trailing dot domain without doing any verification that we are allowed to use that domain, which is the case for S3 as well. One example of this is a report we published on HackerOne back in 2014. However, if you want a custom domain pointing to a bucket using SSL, you need to use CloudFront.
We made contact with both the Chromium and Mozilla security teams to discuss the issue with trailing dot domains on the web. We contacted AWS together with Chromium and AWS fixed the issue in about a week, redirecting all trailing dot domains to the regular domain. We also reported this issue to the companies which were vulnerable to this attack, especially the ones we found that had an EV-SSL on CloudFront.
Our suggestion to the browser vendors was to at least downgrade the “Green Bar” when the domain had a trailing dot. We think that SSL should be as strict as the SOP. A SSL-cert issued for the trailing dot domain should be the only way to get a valid SSL on the trailing dot domain in the first place.
As we see it, there’s no meaning behind showing a domain is verified, as in the case of PayPal, when it’s up to the cloud provider to decide if their conflict check handles trailing dot domains or not. Extended Validation means nothing when neither the SSL-issuer or site (PayPal in this case) has done anything wrong. While there are no technical differences between a regular SSL and an EV-SSL, EV-SSL and its design is built very much on trust, a trust which trailing dot domains clearly break.
What do you think? We would love to know. Ping us at @detectify.
Thanks to mandatory, bored-engineer, yaworsk, michiel and reed for proof reading and giving suggestions on this post.