Restrict Amazon CloudFront and http referrer [duplicate] - amazon-web-services

I have this settings on my s3 bucket policy, where I allow only my cloudfront and referer to access the files on the bucket. I also used Signed URL.
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ABCD1234"
]
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-files/*",
"Condition":{
"StringLike":{"aws:Referer":[
"https://example.com/*"
]}
}
}
]
}
And on the cloudfront behavior, I added the Referer here
Then, invalidate the cache.
Before setting the referer on s3 bucket policy, I can still access my files with signed url. But after setting up the aws:Referer Condition and invalidate the cache, I cannot access my files. It shows 403 Forbidden status.
What settings did I missed? Or is it possible to use Cloudfront OAI with Referer?

What settings did I missed? Or is it possible to use Cloudfront OAI with Referer?
You shouldn't use referrer, as you use OAI. This means that CF will use AWS API to get your objects, not regular HTTP(s) requests. In that case aws:Referer is not used:
This key is included in the request context only if the request to the AWS resource was invoked by linking from a web page URL in the browser. This key is not included for programmatic requests because it doesn't use a browser link to access the AWS resource.

Related

AWS Cloudfront - S3 with CloudFront Origin Access and Referer bucket policy

I have this settings on my s3 bucket policy, where I allow only my cloudfront and referer to access the files on the bucket. I also used Signed URL.
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ABCD1234"
]
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-files/*",
"Condition":{
"StringLike":{"aws:Referer":[
"https://example.com/*"
]}
}
}
]
}
And on the cloudfront behavior, I added the Referer here
Then, invalidate the cache.
Before setting the referer on s3 bucket policy, I can still access my files with signed url. But after setting up the aws:Referer Condition and invalidate the cache, I cannot access my files. It shows 403 Forbidden status.
What settings did I missed? Or is it possible to use Cloudfront OAI with Referer?
What settings did I missed? Or is it possible to use Cloudfront OAI with Referer?
You shouldn't use referrer, as you use OAI. This means that CF will use AWS API to get your objects, not regular HTTP(s) requests. In that case aws:Referer is not used:
This key is included in the request context only if the request to the AWS resource was invoked by linking from a web page URL in the browser. This key is not included for programmatic requests because it doesn't use a browser link to access the AWS resource.

The website hosted on EC2 not able to access S3 image link

I have assigned a role of Fulls3Access to EC2. the website on EC2 are able to upload and delete S3 objects but access to the s3 asset url are denied(which mean I can't read the images). I have enable the block public access settings. Some of folders I want to make it confidential and only the website can access those. I have tried to set conditions on public read like sourceIp and referer url on bucket policy, but below doesn't work, the images on website still don't display. Anyone have ideas to enable and also restrict read s3 bucket access to the website only?
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": [
"arn:aws:s3:::bucketname/assets/*", ]
},
{
"Sid": "AllowIP",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": [
"arn:aws:s3:::bucketname/private/*",
],
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"ip1/32",
"ip2/32", ]
}
}
}
]
}
If you're trying to serve these assets in the users browser via an application on the EC2 host then the source would not be the EC2 server, instead it would be the users browser.
IF you want to restrict assets there are a few options to take whilst allowing the user to see them in the browser.
The first option would be to generate a presigned URL using the AWS SDK. This will create an ephemeral link that will expire after a certain length of time, this would require generation whenever the asset would be required which would work well for sensitive information that is not access frequently.
The second option would be to add a CloudFront distribution in front of the S3 bucket, and use a signed cookie. This would require your code to generate a cookie which would then be included in all requests to the CloudFront distribution. It allows the same behaviour as a signed URL but only requires to be generated once for a user to access all content.
If all assets should only be accessed from your web site but are not considered sensitive you could also look at adding a WAF to a CloudFront distribution in front of your S3 bucket. This would be configured with a rule to only allow where the "Referer" header matches your domain. This can still be bypassed by someone setting that header in the request but would lead to less crawlers hitting your assets.
More information is available in the How to Prevent Hotlinking by Using AWS WAF, Amazon CloudFront, and Referer Checking documentation.

How do I restrict S3 + Cloudfront staging server to specific IP?

I am trying to setup my staging server to be served via S3 and cloudfront. Here is my bucket policy below.
a) If I access the S3 url directly, everything works fine.
b) If I access the cloudfront root domain, www.staging.example.com, everything works fine.
However, once I go to www.staging.example.com/login (or any non-root url), I get a 403 Forbidden AccessDenied error. How do I fix this?
{
"Version": "2012-10-17",
"Id": "S3PolicyId1",
"Statement": [
{
"Sid": "IPAllow",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::staging-server/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"XXX",
"XXX",
]
}
}
}
]
}
If your intention is to serve the site via CloudFront only, then you should reconfigure the S3 bucket policy to allow access to the CloudFront Origin Access Identity of your CloudFront distribution, and remove all IP address conditions from the bucket policy.
To restrict access to the distribution to an IP whitelist, configure AWS WAF and an IPSet. Use WAF v2, not the original WAF.
On the non-root url question, do you actually have a document named login?

Restrict access to s3 static website behind a cloudfront distribution

I want to temporarily restrict users from being able to access my static website hosted in s3 which sits behind a cloudfront distribution.
Is this possible and if so what methods could i use to implement this?
I've been able to restrict specific access to my s3 bucket by using a condition in the bucket policy which looks something like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "12.34.56.73/32"
}
}
}
]
}
which works and restricts my s3 bucket to my ip, however this means that the cloudfront url gets 403 forbidden: access denied.
When reading the AWS docs, it suggests that to restrict specific access to s3 resources, use an Origin Access Identity. However they specify the following:
If you don't see the Restrict Bucket Access option, your Amazon S3 origin might be configured as a website endpoint. In that configuration, S3 buckets must be set up with CloudFront as custom origins and you can't use an origin access identity with them.
which suggests to me that i can't use it in this instance. Ideally i'd like to force my distribution or bucket policy to use a specific security group and control it that way so i can easily add/remove approved ip.
You can allow CloudFront IP addresses on CloudFront because static website endpoint doesn't support Origin access identity.
Here is the list of CloudFront IP addresses:
http://d7uri8nf7uskq.cloudfront.net/tools/list-cloudfront-ips
This link also explains how you can limit access via referral headers
https://aws.amazon.com/premiumsupport/knowledge-center/cloudfront-serve-static-website/
You can tell CloudFront to add a header to every request and then modify your S3 bucket policy to require that header.
E.g.
{
"Version":"2012-10-17",
"Id":"http referer policy example",
"Statement":[
{
"Sid":"Allow get requests originating from www.example.com and example.com.",
"Effect":"Allow",
"Principal":"*",
"Action":"s3:GetObject",
"Resource":"arn:aws:s3:::examplebucket/*",
"Condition":{
"StringLike":{"aws:Referer":"mysecretvalue"}
}
}
]
}

How to get a file in a S3 bucket that was uploaded using Cloudfront?

I am currently trying to implement Cloudfront upload (POST/PUT methods) on an existing S3 bucket.
My Cloudfront distribution seems well-configured.
I am using Cloudfront signed urls to upload my files in the S3 bucket. It works fine.
Once the files uploaded, I can access them using Cloudfront signed url. It is fine too.
But I observe that I cannot access the uploaded files (via Cloudfront) using the AWS credentials (access_key_id & secret_key).
Everytime, I try this, I receive an AccessDenied error code.
I feel like something is missing in the configuration of the S3 bucket policy.
Here is my current S3 bucket policy:
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXXXXX",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::XXXXX-XXXXXX-XXXX/*"
}
]
}
Did I miss something or is it just impossible?
I did have the same issue once.
Try to add the header "x-amz-acl=bucket-owner-full-control" to the upload request and that should do the trick.