Skip to content

Cloudfront: subdomain in viewer request unexpectedly used in origin request

0

Hi all,

I have a CloudFront distribution which is configured as follows:

  • Alternate domain names: mywebsite.com, *.mywebsite.com
  • One origin which is s3 website endpoint of the bucket named mywebsite.com i.e. mywebsite.com.s3-website-ap-southeast-2.amazonaws.com
  • Behaviours: serve the above origin at all paths, caching disabled

Visiting mywebsite.com serves the contents of the bucket, as expected.

I would also expect the same set of files to be served when visiting argh.mysebsite.com however this is not the case. Instead, CloudFront seems to attempt to make a request to argh.mywebsite.com.s3-website-ap-southeast-2.amazonaws.com to which I receive the following response:

HTTP 404 , Code: NoSuchBucket Message: The specified bucket does not exist BucketName: argh.mywebsite.com RequestId: <stuff> HostId: <stuff>

Is this expected behaviour? To me it seems strange that the subdomain in the viewer request has leaked through to the request made to the origin. I would've expected the configured origin URL to be honoured regardless of the domain of the viewer request.

PS I'm aware that this design is vulnerable to domain hijacking by bad actors so it is not a set up I currently use nevertheless it is an interesting thought experiment.

asked a year ago285 views
1 Answer
1

CloudFront Origin Request Logic:

When you set up a CloudFront distribution with alternate domain names (e.g., mywebsite.com, *.mywebsite.com), CloudFront will forward requests to the origin based on how the request was made by the viewer. If the viewer requests argh.mywebsite.com, CloudFront, by default, will use argh.mywebsite.com as the Host header when making the request to the origin.

S3 Website Endpoint Behavior:

When your origin is an S3 website endpoint (e.g., mywebsite.com.s3-website-ap-southeast-2.amazonaws.com), S3 expects the bucket name to match the Host header in the request. In your case, when CloudFront forwards the request for argh.mywebsite.com, S3 tries to find a bucket named argh.mywebsite.com, leading to the NoSuchBucket error because such a bucket doesn't exist.

Why is This Happening?

CloudFront’s default behavior is to pass through the Host header from the viewer’s request to the origin. Since S3 website endpoints determine which bucket to serve based on the Host header, this results in S3 looking for a non-existent bucket corresponding to the subdomain.

How to Control This Behavior

To ensure that all subdomain requests (*.mywebsite.com) are served from the mywebsite.com bucket, you need to modify the behavior of CloudFront so that it always sends the correct Host header to the origin. Here are two approaches:

**Option 1: ** Use a Lambda@Edge Function to Rewrite the Host Header

You can attach a Lambda@Edge function to the Origin Request event to rewrite the Host header so that it always points to mywebsite.com, regardless of the viewer’s subdomain.

Example Lambda@Edge Function:

def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']
    headers = request['headers']
    
    # Set the Host header to the correct S3 bucket
    headers['host'] = [{'key': 'Host', 'value': 'mywebsite.com.s3-website-ap-southeast-2.amazonaws.com'}]
    
    return request

Deploy this function to the appropriate AWS region.

Attach it to your CloudFront distribution on the Origin Request event.

Option 2: Use a CloudFront Behavior with a Custom Origin Request Policy

Instead of Lambda@Edge, you can create an origin request policy that overrides the Host header.

Create a Custom Origin Request Policy:

Go to the CloudFront console.

Create a new origin request policy.

In the policy settings, configure it to include a specific Host header value (mywebsite.com.s3-website-ap-southeast-2.amazonaws.com).

Apply the Policy to the Distribution:

Edit your CloudFront distribution.

Assign the custom origin request policy to the behavior that routes traffic to your S3 origin.

EXPERT
answered a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.