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.
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.
Environment
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.
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
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.
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.
Referer header condition is set.
Confirmation of Operation
Now that everything is ready, access the CloudFront distribution.
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.
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.