How to use referer condition in Amazon S3 bucket policy with CloudFront - amazon-web-services

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)

Related

S3 Policy Deny for all principals but

I am attempting to deny public users from accessing signedUrl paths directly, unless it's loaded by my website <img> tag.
Typical users should not allow to copy the image URL directly in the address bar and download the image.
The allow policy
{
"Sid": "Allow public with signedUrl",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::my-chat-attachments-development/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"http://localhost:4000/*",
"http://localhost:3000/*",
"https://mydomain1/*",
"https://mydomain2/*"
]
}
}
},
Below explicitly deny public access. Without the following policy, public users can still copy and paste image URL directly in the address bar (undesirable).
{
"Sid": "Statement to deny anybody without referrer",
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::1234:user/S3UserfullAccess",
"arn:aws:iam::1234:role/LambdaFullAccess"
]
},
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::my-chat-attachments-development/*",
"Condition": {
"StringNotLike": {
"aws:Referer": [
"http://localhost:4000/*",
"http://localhost:3000/*",
"https://mydomain1/*",
"https://mydomain2/*"
]
}
}
}
Problem
I have the above policy settings, and it works well (public users are shown a access denied page). However, it also means my lambda, and my nodejs app servers cannot access the S3 even though I added NotPrincipal in the policy.
Please advise how can I correct my policy to achieve my desire behavior.
PS: I do note the above referer hack will not stop technical users from spoofing referring addresses.

Electron-Updater and AWS S3 bucket policy - Error: HttpError: 403 Forbidden

I am creating an Electron.js app and I am using S3 to host the new releases of my app. I can't leave the S3 bucket open to the public and need to limit it only to the users in the company where the app will be used. Therefore, I decided to limit access to the bucket by the company's IP address. However, when Electron-updater checks for an update, I get the Error: HttpError: 403 Forbidden. This is the bucket policy I am using:
{
"Version": "2012-10-17",
"Id": "S3PolicyId1",
"Statement": [
{
"Sid": "IPAllow",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::BUCKETNAME",
"arn:aws:s3:::BUCKETNAME/*"
],
"Condition": {
"NotIpAddress": {
"aws:SourceIp": "Company's IP Address"
}
}
}
]
}
When Electron-Updater checks to see if there is a new update, I get the Error: HttpError: 403 Forbidden. It shouldn't be, because the request is coming from the IP of the company. I am wondering if maybe for some reason the request is coming from a different IP. I tried to use the S3 access logs (I have never used them), but nothing gets saved in the bucket I create to store those logs. I am at a loss as to what the problem is.
If I understood the Question, you want Allow Only from Specific IP's.
{
"Version": "2012-10-17",
"Id": "S3PolicyId1",
"Statement": [
{
"Sid": "IPAllow",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::BUCKETNAME",
"arn:aws:s3:::BUCKETNAME/*"
],
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"CIDR",
"CIDR"
]
}
}
}
]
}

AWS S3 Bucket Policy security

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

Amazon S3 bucket policy for referer condition on specific folder

I want to use condition of StringLike aws:Referer for a particular folder and make rest of the folder publicly accessible.
Here is my bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::bucketName/folderName/*"
]
},
{
"Sid": "",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucketName/folderName/users/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"https://example.com/*"
]
}
}
}
]
}
When I am using above policy, it is not working with first one.
Try with below policy:
{
"Sid": "",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucketName/folderName/users/*",
"Condition": {
"StringNotLike": {
"aws:Referer": [
"https://example.com/*"
]
}
}
}
The first part of your policy is granting GetObject access for anything in the folderName path of your bucket. This includes folderName/users/*.
Therefore, the second part of your policy is not being used (since the first policy is already granting access to the folderName/users/* path.
You could solve it by using different buckets, or you could convert the second policy into a Deny with StringNotLike (effectively saying that access is denied to folderName/users/* if the referer is not example.com.
Frankly, your policy looks strange because it is granting access to the entire users path hierarchy, which probably isn't what you'd want it to do. (I'm assuming you'd want to grant access only to a particular user's data based upon who is accessing your application.)
Please note that referer is not secure — it is easy to fake this value in a browser and in web-scraping softare.

Amazon S3 - add local computer to list of allowed referers

I have a bucket policy in place (below) that only allows access to S3 from our remote website (to prevent hotlinking). I'd like to also be able to access the files when working from our local computer. I've tried adding my ip address, local ip, and localhost to aws:Referer but that hasn't worked.
For the task I'm trying to accomplish, I'd like to be able to directly access the files in my browser using the direct link: https://s3.amazonaws.com/[bucket]/[filename]
Any suggestions? Thanks!
{
"Version": "2012-10-17",
"Id": "http referer policy example",
"Statement": [
{
"Sid": "Allow get requests referred by www.mysite.com and mysite.com",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::[bucketname]/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"http://www.[mysite].com/*",
"http://192.168.1.6/*",
"http://foundwaves.com/*",
"http://[ip]/*",
"http://localhost/*"
]
}
}
},
{
"Sid": "Explicit deny to ensure requests are allowed only from specific referer.",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::foundwaves/*",
"Condition": {
"StringNotLike": {
"aws:Referer": [
"http://www.[mysite].com/*",
"http://192.168.1.6/*",
"http://foundwaves.com/*",
"http://[ip]/*",
"http://localhost/*"
]
}
}
}
]
}