Aws s3 read only bucket policy not working with cloudfront - amazon-s3

I have made a S3 bucket policy for readonly access to cloudfront, i want to restrict s3 bucket for public and just allow it from referrer urls via cloudfront how ever it is not applying my s3 bucket policy.
{
"Version": "2012-10-17",
"Id": "http referer",
"Statement": [
{
"Sid": "Allow get requests referred by www.def.com and dev.def.com.",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXXXX"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::devmb/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"http://www.def.com/*",
"http://dev.def.com/*"
]
}
}
},
{
"Sid": "Explicit deny to ensure requests are allowed only from specific referer.",
"Effect": "Deny",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXXXXXX"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::devmb/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"http://dev.xyx.com/*",
"http://blog.xyz.com/*"
]
}
}
}
]
}
My content is public right now.

Referer does not work when using CloudFront because the referer does not appear in the HTTP request header itself. You'll have to use S3 without CloudFront if you wish to restrict access using conditional aws:Referer in the bucket policy.

Related

S3 Bucket Policy to work with CloudFront GetObject and PutObject directly to the bucket using Multer-S3

I am trying to make a S3 bucket policy that only allows GetObject from CloudFront but able to PutObject directly to the bucket.
Tried with several combinations but none of the worked.
Here is the latest attempt that I tried.
With, Block All Public Access: ALL OFF.
Bucket Policy:
{
"Version": "2012-10-17",
"Id": "Policy1604429581591",
"Statement": [
{
"Sid": "Stmt1605554261786",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::MYBUCKET/*"
},
{
"Sid": "Stmt1605557746418",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::MYBUCKET/*"
},
{
"Sid": "Stmt1605557857544",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:MYCLOUDFRONT"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::MYBUCKET/*"
}
]
}
This allows me to PutObject to the bucket but GetObject using CloudFront URL got access denied. If I removed
{
"Sid": "Stmt1605557746418",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::MYBUCKET/*"
}
I can GetObject from CloudFront as well as from bucket directly.
Please help!
Found the solution of it.
First follow the instructions here to setup CloudFront: https://aws.amazon.com/premiumsupport/knowledge-center/cloudfront-access-to-amazon-s3/. Key point is
5. For Restrict Bucket Access, select Yes.
I was using Multer-S3 to upload my image files. ACL needs to be set to
acl: 'authenticated-read',
Also I am using serverSideEncryption, in S3 bucket properties=>Default encryption
Default encryption: Enabled
Server-side encryption: Amazon S3 master-key(SSE-S3)
Multer-S3 config
serverSideEncryption: 'AES256',
S3 Bucket permission un-Block all public access and ACL only enables Bucket Owner's permissions.
The final bucket policy I have is:
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E36AHAEXL422P3"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::MYBUCKET/*"
},
{
"Sid": "Stmt1605745908405",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::MYBUCKET/*",
"Condition": {
"StringEqualsIfExists": {
"s3:x-amz-server-side-encryption": "AES256"
}
}
}
]
}
With all above configurations, this allows PubObject from anyone as long as requests have server side encryption with 'AE256'. GetObject requests directly to the bucket will be blocked. All GetObject requests need to go through CloudFront.

S3 + Cloudfront : files are allowed but folders are blocked

I have a problem where files are perfectly accessible from my bucket, but folders throw an access denied error. Does anyone know how I can solve this? I want my folders to be accessible too.
Here is my bucket policy:
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "DenyS3PublicObjectACL",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObjectAcl",
"Resource": [
"arn:aws:s3:::xxxxx/*”,
"arn:aws:s3:::xxxxx”
],
"Condition": {
"StringEqualsIgnoreCaseIfExists": {
"s3:x-amz-acl": [
"authenticated-read",
"public-read",
"public-read-write"
]
}
}
},
{
"Sid": "2",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXXXX”
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::xxxxx/*”
}
]
}
You won't get a directory listing page out of Amazon S3 when accessing the URL. S3 doesn't show directory listing.
Reference : S3 allow public directory listing of parent folder?
If you want to implement directory structure explorer see this plugin.
https://github.com/awslabs/aws-js-s3-explorer - Recommended
https://github.com/rufuspollock/s3-bucket-listing

Allow videos on s3 bucket to be loaded only from a particular URL

My requirement is to be able to load videos via https only from a particular URL (e.g. "https://www.app.myurl.com").
Is that possible?
If yes how?
Here is what I tried.
1) Place video on S3 Bucket.
And setup the guideline.
"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:::mybucketname/*",
"Condition": {
"StringLike": {
"aws:Referer": "https://app.sampleurl.at/*"
}
}
}
]
}
It doesn't seem to to what I want. All I can do is change the ACL on file level to either be accessible for everyone or for none.

Force SSL on Amazon S3

Is it possible (via IAM, bucket policy, or otherwise) to force Amazon S3 to only serve content over HTTPS/SSL and deny all regular, unencrypted HTTP access?
I believe this can be achieved using a bucket policy. Deny all HTTP requests to the bucket in question using the condition aws:SecureTransport: false.
The following is not tested but it should give you an idea of how to set it up for your case.
{
"Statement":[
{
"Action": "s3:*",
"Effect":"Deny",
"Principal": "*",
"Resource":"arn:aws:s3:::bucketname/*",
"Condition":{
"Bool":
{ "aws:SecureTransport": false }
}
}
]
}
Here you allow your incoming traffic but refuse the non SSL one. If you want to go back just remove the 2nd statement:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::yourbucketnamehere/*"
},
{
"Sid": "PublicReadGetObject",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::yourbucketnamehere/*",
"Condition":{
"Bool":
{ "aws:SecureTransport": false }
}
}
]
}
Don't forget to put your bucket name at yourbucketnamehere.
Now you need to install a SSL certificate. All the information can be found here.

amazon S3 bucket policy - restricting access by referer BUT not restricting if urls are generated via query string authentication

I have the following bucket policy set on my bucket:
{
"Version": "2008-10-17",
"Id": "My access policy",
"Statement": [
{
"Sid": "Allow only requests from our site",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my_bucket/*",
"Condition": {
"StringLike": {
"aws:Referer": [
" http://example.com/*",
" http://www.example.com/*"
]
}
}
},
{
"Sid": "Dont allow direct acces to files when no referer is present",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my_bucket/*",
"Condition": {
"Null": {
"aws:Referer": true
}
}
}
]
}
I also configured query string authentication, but it looks like I can't have both. If I have my bucket policies set to deny any request that doesn't originate from example.com, my temporary url using query string authentication will also not get served. So my question is, how can i have both ? Is there a way to check for url parameters and see if it has a parameter called "Signature" and in that case not apply the referer policy?
Remove the space in the referrers string " http://example.com/*" that's wrong... the Amazon examples made that mistake too (using "mydomain" instead of "example").
For the second statement the easier way to solve it is to remove that entire statement and have your files permissions (ACLs) set to private (Owner-Read/Write and World-NoRead/NoWrite)
I am not sure, but in appears that even if you have a Deny Statement a file can still be read if it has a public permission (World Read).
Also, if you are distributing the files on CloudFront remember to allow it to read the bucket too. So a complete bucket policy will look like:
{
"Version": "2008-10-17",
"Id": "YourNetwork",
"Statement": [
{
"Sid": "Allow get requests to specific referrers",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::yourbucket/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"http://www.yourwebsite.com/*",
"http://yourwebsite.com/*"
]
}
}
},
{
"Sid": "Allow CloudFront get requests",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::12345678:root"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::yourbucket/*"
}
]
}
(change the 12345678 to your AWS account ID number without the dashes)