I am days researching how CORS works on AWS S3 but I can’t configure it at all.
I need my files to NOT be publicly accessible, BUT they can be incorporated into my domains. Currently I am unable to incorporate my images into my domains, access to them is completely blocked, as if CORS did not exist.
AWS Block Public Access
CORS settings
[
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE"],
"AllowedOrigins": [
"https://www.dev.seedlix.com.br/",
"https://dev.seedlix.com.br/",
"http://www.dev.seedlix.com.br/",
"http://dev.seedlix.com.br/",
"https://www.seedlix.com.br/",
"https://seedlix.com.br/",
"http://www.seedlix.com.br/",
"http://seedlix.com.br/",
"http://localhost:3000/",
"52.95.163.31:443"
],
"ExposeHeaders": []
}
]
After many hours of research, I finally managed to do what I wanted. First of all, I left all Bucket Accessible, and then I created a Policy that blocks access to EVERYONE except for requests originating from my domains.
Bucket Public Access
Bucket Policy
{
"Version": "2012-10-17",
"Id": "http referer policy example",
"Statement": [
{
"Sid": "Allow get requests originating custom domains.",
"Effect": "Deny",
"Principal": "*",
"Action": ["s3:GetObject", "s3:GetObjectVersion"],
"Resource": "arn:aws:s3:::BUCKET_NAME_HERE/*",
"Condition": {
"StringNotLike": {
"aws:Referer": [
"https://domain-a.com.br/*",
"https://domain-b.com/*",
]
}
}
}
]
Bucket Cors Policy
Related
Requirement:
We're using AWS CloudFront with S3 bucket for my client to save the tutorial/course videos, hence we would like to prevent the users to download any video with the links either S3 Object link or CloudFront domain url. In other words only with our website these will be readable / accessible or users can only be able to watch them. Therefore, we're trying to restrict the access through direct links.
Tried solution:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "S3PublicRead",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"s3:GetObject",
"s3:GetObjectTagging",
"s3:PutObject",
"s3:PutObjectTagging"
],
"Resource": [
"arn:aws:s3:::DOC-EXAMPLE-BUCKET",
"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
],
"Condition": {
"StringLike": {
"aws:Referer": [
"https://dev.mycompany.com/",
"https://mycompany.com/"
]
}
}
},
{
"Sid": "CloudFrontPublicRead",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity AAAAAAAAAAA"
},
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::DOC-EXAMPLE-BUCKET",
"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
],
"Condition": {
"StringLike": {
"aws:Referer": [
"https://dev.mycompany.com/",
"https://mycompany.com/"
]
}
}
}
]
}
Problem:
The above policy is working fine with the S3 object urls, like If I open it through the link it is showing Access Denied and within my website the videos are playing fine.
However, the video links with CloudFront Domain, not accessible even within the website. We need the same behavior as with the S3 direct URLs.
Conclusion:
The aws:Referer condition is working fine with s3 object urls but not applying on the CloudFront url, hence making them unaccessible.
Hopefully, I'm able to state the problem as it is occurring.
Thanks in advance.
More Info:
Cloudfront Distribution Behavior Details:
Listing
Details of the second entry (Default)
I will be using Cloudflare as a proxy for my S3 website bucket to make sure users can't directly access the website with the bucket URL.
I have an S3 bucket set up for static website hosting with my custom domain: www.mydomain.com and have uploaded my index.html file.
I have a CNAME record with www.mydomain.com -> www.mydomain.com.s3-website-us-west-1.amazonaws.com and Cloudflare Proxy enabled.
Issue: I am trying to apply a bucket policy to Deny access to my website bucket unless the request originates from a range of Cloudflare IP addresses. I am following the official AWS docs to do this, but every time I try to access my website, I get a Forbidden 403 AccessDenied error.
This is my bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CloudflareGetObject",
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::ACCOUNT_ID:user/Administrator",
"arn:aws:iam::ACCOUNT_ID:root"
]
},
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::www.mydomain.com/*",
"arn:aws:s3:::www.mydomain.com"
],
"Condition": {
"NotIpAddress": {
"aws:SourceIp": [
"2c0f:f248::/32",
"2a06:98c0::/29",
"2803:f800::/32",
"2606:4700::/32",
"2405:b500::/32",
"2405:8100::/32",
"2400:cb00::/32",
"198.41.128.0/17",
"197.234.240.0/22",
"190.93.240.0/20",
"188.114.96.0/20",
"173.245.48.0/20",
"172.64.0.0/13",
"162.158.0.0/15",
"141.101.64.0/18",
"131.0.72.0/22",
"108.162.192.0/18",
"104.16.0.0/12",
"103.31.4.0/22",
"103.22.200.0/22",
"103.21.244.0/22"
]
}
}
}
]
}
By default, AWS Deny all the request. Source
Your policy itself does not grant access to the Administrator [or any other user], it only omits him from the list of principals that are explicitly denied. To allow him access to the resource, another policy statement must explicitly allow access using "Effect": "Allow". Source
Now, we have to create Two Policy Statment's:- First with Allow and Second with Deny. Then, It is better to have only One Policy With "allow" only to Specific IP.
It is better not to complicate simple things like using Deny with Not Principal and NotIPAddress. Even AWS says :
Very few scenarios require the use of NotPrincipal, and we recommend that you explore other authorization options before you decide to use NotPrincipal. Source
Now, the questions come on how to whitelist Cloudflare IP's???.
Let's go with a simple approach. Below is the Policy. Replace your bucket name and your Cloudflare Ip's. I have tested it and it is running.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudFlareIP",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:getObject",
"Resource": [
"arn:aws:s3:::my-poc-bucket",
"arn:aws:s3:::my-poc-bucket/*"
],
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"IP1/32",
"IP2/32"
]
}
}
}
]
}
I am performing Amazon Athena queries on an S3 bucket. Let's call it athena-bucket. Today I got a requirement to restrict this bucket over VPC Enpoints. So I have tried this S3 bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VPCe and SourceIP",
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::**********:user/user_admin",
"arn:aws:iam::**********:root",
]
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::athena-bucket",
"arn:aws:s3:::athena-bucket/abc/*"
],
"Condition": {
"StringNotEquals": {
"aws:sourceVpce": [
"vpce-XXXXxxxxe",
"vpce-xxxxxxxxxx",
"vpce-XXXXXXXXXXXXXX"
]
},
"NotIpAddress": {
"aws:SourceIp": [
"publicip/32",
"publicip2/32"
]
}
}
}
]
}
Please note that Athena has full permission to access the above bucket. I want to use the S3 bucket policy to restrict access from only certain IP addresses and VPC Endpoint.
However, I am getting access denied error although request is routed through VPC Endpoints mentioned in the policy.
Amazon Athena is an Internet-based service. It accesses Amazon S3 directly and does not connect via an Amazon VPC.
If you restrict the bucket to only be accessible via a VPC Endpoint, Amazon Athena will not be able to access it.
There is actually a solution for you to get what you are asking for. The following policy condition allows actions from all of your VPC endpoints and Athena:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VPCe and SourceIP",
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::**********:user/user_admin",
"arn:aws:iam::**********:root",
]
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::athena-bucket",
"arn:aws:s3:::athena-bucket/abc/*"
],
"Condition": {
"ForAllValues:StringNotEquals": {
"aws:sourceVpce": [
"vpce-XXXXxxxxe",
"vpce-xxxxxxxxxx",
"vpce-XXXXXXXXXXXXXX"
],
"aws:CalledVia": [ "athena.amazonaws.com" ]
}
}
}
]
}
The "ForAllValues" portion of the condition is what turns this AND condition into an OR.
Not sure how your IP restrictions would play with this, since you cannot tell which IPs Athena would be coming from.
I have a website where the users can upload files like images or pdfs, and I'm storing them in AWS S3. It's working correctly, but I put a "public policy" to test it like this one:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::mybucket/*"
]
}
]
}
It works but I think that a malicius user could make a lot of requests and amazon charge me for that. So what would be the way to limit the access but keep working correctly with my webapp?
Thanks in advance.
You could create a time-limited Amazon S3 pre-signed URL for those objects. This grants access to a private object for a limited time.
You can Restrict Access to Specific HTTP Referrer by modifying your bucket policy like this.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::mybucket/*"
],
"Condition": {
"StringLike": {
"aws:Referer": [
"http://www.example.com/*",
"http://example.com/*"
]
}
}
}
]
}
Replace example.com with your website name.This allows the objects can be only accessed from domain staring with your domain name. Make sure the browsers you use include the http referer header in the request . For more details see Restricting Access to a Specific HTTP Referrer
Our website is currently being scraped by bots to acccess content on S3. I'm trying to get a bucket policy setup so that a S3 URL cannot be accessed by any other referrer except our domain. Problem is that it doesn't seem to detect that our domain is the referrer. Here is the bucket policy we have setup below.
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "AllowPublicRead",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example/*",
"Condition": {
"StringNotLike": {
"aws:Referer": [
"https://www.example.com/*",
"http://www.example.com/*",
"https://*.example.com/*",
"https://*.example.com/*"
]
}
}
}
]
}
Does anyone know why it wouldn't recognize www.example.com/blah/blah.html etc. as the referrer?
Is there a way to see see what AWS is registering as the referrer when I access a URL via our app? That would help with troubleshooting.
From Bucket Policy Examples - Restricting Access to a Specific HTTP Referrer:
{
"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":["http://www.example.com/*","http://example.com/*"]}
}
}
]
}
This policy is Allowing access if the Referer string is like those shown in the list.
Your cost is using StringNotLike, so it is only permitting access if the Referer is not one that you listed.