S3 content delivery via CloudFront – Referer hreader ver

TOC

Restricting access to origin with Referer header when delivering S3 content from CloudFront

The following page shows how to deliver content from an S3 bucket with static website hosting enabled via CloudFront.

あわせて読みたい
S3 content delivery via CloudFront – Static website hosting ver 【Delivering S3 Content via CloudFront】 CloudFront, a CDN service, can be used to deliver content placed in S3 buckets.This time, we will enable the static ...

However, there is one issue with the above configuration.
That is that the origin S3 bucket can be directly accessed.

This time, we aim to enforce access via CloudFront by referring to the following official page.

https://aws.amazon.com/premiumsupport/knowledge-center/cloudfront-serve-static-website/?nc1=h_ls

Here is a summary of the key points of the method we will introduce.

  • CloudFront: Set the Referer header in the origin custom header.
  • S3: Include the value of the Referer header in the conditions for allowing access to the content in the bucket policy.

The use of an OAI (Origin Access Identity) can also be used to achieve actions similar to those in this configuration. Please check this page as well.

あわせて読みたい
S3 content delivery via CloudFront – Referer hreader ver 【Restricting access to origin with Referer header when delivering S3 content from CloudFront】 The following page shows how to deliver content from an S3 bu...

Environment

Diagram of S3 content delivery via CloudFront - Referer header ver

The overall configuration is the same as before.
Configure the CloudFront and S3 bucket policies with the Referer header.

CloudFormation template files

The above configuration is built with CloudFormation.
The CloudFormation template is located at the following URL

https://github.com/awstut-an-r/awstut-fa/tree/main/049

Point Explanation of Template Files

This page focuses on how to restrict access to the origin using the Referer header.
For other contents, please refer to the page introduced at the beginning of this document.

Configuring Origin Custom Headers in CloudFront

Resources:
  Distribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        DefaultCacheBehavior:
          AllowedMethods:
            - GET
            - HEAD
          CachedMethods:
            - GET
            - HEAD
          Compress: true
          ForwardedValues:
            Cookies:
              Forward: none
            QueryString: false
          TargetOriginId: !Ref BucketName
          ViewerProtocolPolicy: allow-all
        Enabled: true
        Origins:
          - DomainName: !Select
              - 2
              - !Split
                  - /
                  - !Ref BucketWebsiteURL
            Id: !Ref BucketName
            CustomOriginConfig:
              OriginProtocolPolicy: http-only
            OriginCustomHeaders:
              - HeaderName: Referer
                HeaderValue: !Ref Prefix
        PriceClass: PriceClass_All
Code language: YAML (yaml)

In S3 buckets with the static website hosting feature enabled, access restriction using Referer headers is an effective way to enforce access through CloudFront.

This configuration restricts access by setting up a custom Referer header on the distribution, and then uses a bucket policy to allow access only for requests with the custom Referer header.

How do I use CloudFront to serve a static website hosted on Amazon S3?

If you want to customize the header when accessing the origin from CloudFront, you can do so with the OriginCustomHeaders property.
Inside this property, the HeaderName and HeaderValue properties can be used to set the header information.
Following the above quote, the HeaderName property should be set to “Referer”.
The official website explains the value that should be set for the HeaderValue property as follows

For Value, enter a customer header value that you want to forward to the origin (S3 bucket). To restrict access to the origin, enter a random or secret value that only you know.

How do I use CloudFront to serve a static website hosted on Amazon S3?

So this time we will use the built-in function Fn::Ref to set the string “fa-049”.

Include value of Referer header in bucket policy as Condition

Resources:
  BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref Bucket
      PolicyDocument:
        Statement:
          Action:
            - s3:GetObject
          Effect: Allow
          Resource: !Sub "arn:aws:s3:::${Bucket}/*"
          Principal: "*"
          Condition:
            StringLike:
              aws:Referer:
                - !Ref Prefix
Code language: YAML (yaml)

Check the Referer header in the bucket policy.
Refer to the following official website to set it up.

https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies.html#example-bucket-policies-use-case-4

The key point is the Condition property.
By using StringLike and aws:Referer property inside this property, the Referer header value can be checked.
By setting “fa-049” to this item, you can achieve the behavior of allowing access only if this string is set in the Referer header.
This will be equal to the header information set on the CloudFront side, so access will be allowed when accessing via CloudFront.

Architecting

Use CloudFormation to build this environment and check the actual behavior.

Create CloudFormation stacks and check resources in stacks

Create a CloudFormation stacks.
For information on how to create stacks and check each stack, please refer to the following page

あわせて読みたい
CloudFormation’s nested stack 【How to build an environment with a nested CloudFormation stack】 Examine nested stacks in CloudFormation. CloudFormation allows you to nest stacks. Nested ...

After checking the resources in each stack, information on the main resources created this time is as follows

  • S3 bucket: fa-049
  • Wave site endpoint of S3 bucket: http://fa-049.s3-website-ap-northeast-1.amazonaws.com/
  • CloudFront distribution domain: https://d27wmgzizu923r.cloudfront.net/

CloudFront is also checked from the AWS Management Console.

CloudFront Referer header settings.

The S3 bucket website endpoint is set as the origin.
The key point is the header information.
The string “fa-049” is set for the Referer header.

Next, check the bucket policy of the S3 bucket.

Bucket Policy Referer Header Settings.

Referer header condition is set.

Confirmation of Operation

Now that everything is ready, access the CloudFront distribution.

Access results with Referer header set.

The contents of the S3 bucket are now displayed.
This means that the website endpoint of the origin S3 bucket is being accessed via CloudFront.

Next, try accessing the origin S3 bucket directly.

Access results when Referer header is not set.

An error is returned.
The Referer header is not set, which means that access is denied by the bucket policy.

However, there is a problem with this method.
It is still possible to access the origin directly as long as the Referer header is set.
Access the origin after setting the header information with the curl command.

$ curl -H "Referer:fa-049" http://fa-049.s3-website-ap-northeast-1.amazonaws.com/
<html>
  <head></head>
  <body>
    <h1>index.html</h1>
    <p>fa-049</p>
  </body>
</html>
Code language: Bash (bash)

We were able to access the origin directly.
Please note that while this method of restricting access using the Referer header is effective, it is not a panacea.

Summary

We have shown how to use the Referer header to force access via CloudFront when delivering content in S3 buckets.

TOC