Prevent indexing of *.cloudfront.net URLs

When creating a CloudFront distribution, AWS assigns it a generic domain name, such as d2d7frhciy9p7h.cloudfront.net. You can add your own domain as an alias, but the original one cannot be disabled. Your website is then available using either your custom domain or the default .cloudfront.net endpoint.

From a security standpoint, this is not a big deal: this endpoint doesn’t give access to more data than your own domain. However, things start to get messy when search engines add those URLs to their index:

  • Users can stumble upon these plain-looking links when searching for your content, which isn’t good for their experience
  • Search engines like Google can detect that the same content is served from multiple domains, and penalize you for that

The Internet has various answers to that problem. For example, if your origin is Host header aware, you could make sure CloudFront forwards the Host header and then configure your web server to only answer to requests with the right Host.

However, if you don’t want this kind of coupling or if you’re using simpler origins like S3 buckets, there’s another way to do it: CloudFront Functions.

To block access through the .cloudfront.net domain, first create a CloudFront Function with the following code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
function handler(event) {
    var request = event.request;
    var host = request.headers.host.value;

    if (host.endsWith('.cloudfront.net')) {
        return {
            statusCode: 403,
            statusDescription: 'Forbidden',
            headers: {
                'x-reason': {value: 'Access via .cloudfront.net distribution domain name forbidden'}
            }
        };
    } else {
        return request;
    }
}

You can then attach that function to Viewer request events in your distribution’s Behaviors: CloudFront Behavior function associations example

That’s it! Now, when trying to access your .cloudfront.net domain, CloudFront should return HTTP 403 errors: Result example

A drawback is that you can’t set a response body with CloudFront Functions, so the user gets a blank page (which shouldn’t be a problem as nobody’s supposed to reach that domain in the first place).

Cost-wise, the free tier currently includes 2M function executions per month. After that, you’ll get billed $0.10 per million requests.