Make every object in an Amazon S3 bucket publicly accessible - amazon-web-services

I have a S3 bucket on AWS to which I am uploading images from the frontend.
After successfully uploading an image to S3, this is the URL I get -
https://cewa-foundation-2020.s3.amazonaws.com/image8_%281%29.webp-1628768330444.webp
I want to make this URL public so that anyone with this link can view the image.
How can I achieve this?

To make every object public you should add a Bucket Policy to the bucket.
Go to the bucket's Permissions tab
Go to the Block public access options
Turn off the two options that mention Bucket Policies:
Below that, add a Bucket Policy that grants access to anonymous users:
{
"Version":"2012-10-17",
"Statement":[
{
"Sid": "PublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::YOUR-BUCKET-NAME/*"
}
]
}
All objects in the bucket can now be accessed by anyone on the Internet. However, they will not be able to list the contents of the bucket, so they will need to know the exact name of the object they want to access.

You can make an object public by doing these below steps:
Open the object by choosing the link on the object name.
Choose the Permissions tab.
Choose Edit.
In the Everyone section, select Objects Read.
Select I understand the effects of these changes on this object.
Choose Save changes.
This is just one of the ways of doing it. Check the below link for more such ways.
Source: https://aws.amazon.com/premiumsupport/knowledge-center/read-access-objects-s3-bucket/

Related

Make one S3 bucket public

Currently I have 5 S3 buckets in my account, and all of them are Block all public access -> ON and the same setting is also there for Block Public Access settings for this account -> ON.
Now I want to create a new bucket that should be public, and I don't want to change any of my existing buckets. So for the newly created bucket I have set Block all public access = OFF. But when I try to save below policy, it gives Access denied error. So I guess I have to Turn Off Block Public Access settings for this account.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Action": "s3:GetObject",
"Effect": "Allow",
"Resource": "arn:aws:s3:::MyNewImageBucketS3/*",
"Principal": "*"
}
]
}
I want to know that if I turn off account level setting, then will it affect my existing buckets?
As a second option I can configure CloudFront and serve files publicly but want to know about the public access change at the account level.
Block all public access = OFF; this setting is for individual s3 buckets provided you are doing it from bucket settings, so for that specific bucket you can turn this off and you are good to go.
If you want specific objects to be publicly accessible then this can be achieved via similar IAM policy you shared but to make this work turn on public access on that bucket and then you can apply IAM policy to allow specific objects and deny remaining.
Below image describes that if you change it in bucket setting, its going to effect on that specific bucket and the objects within bucket only
For more guidelines please check below AWS doc
https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-policy-alternatives-guidelines.html

How to create correct S3 bucket policy to enable read access to a file only if they know the path

My web app allows different user to upload different files. Currently putting them all in one bucket, something like:
A12345-Something.zip
B67890-Lorem.zip
A12345-... is file uploaded by user id A12345.
B67890-... is file uploaded by user id B67890.
This is my S3 bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::xxxx/*"
}
]
}
So far, this is all good, user A12345 can download the zip file by accessing https://xxxx.s3.ap-south-1.amazonaws.com/A12345-Something.zip
But the AWS interface gives me a warning that this bucket is a public bucket and it is highly recommended to not set it to public.
I am not sure but it is indeed very wrong if the policy above allows someone to list all objects from all users in my bucket and then access them one by one.
I think I need a policy that only allows reading a specific object if the full path is provided (assuming only that user will have access to that full path), but disallow listing of objects?
How should the policy looks like?
The policy you've specified allows someone to get all objects which means if they have the path they can retrieve that file publicly in the browser.
The permission ListObjects would be the permission that allows people to list all of the objects in your S3 bucket, this is not included.
If only specific users should be accessing this content, you should take a look at using signed URLs instead, this would prevent someone guessing or somehow gaining access to a link you do not want them to have.
This warning is in place to protect sensitive data being left exposed to the world, which is recent times has caused large volumes of private company data to be leaked.

File in Amazon S3 bucket denied after making bucket public

I have made my Amazon S3 bucket public, by going to its Permissions tab, and setting public access to everyone:
List objects
Write objects
List bucket permissions
Write bucket permissions
There is now an orange "Public" label on the bucket.
But when I go into the bucket, click on one of the images stored there, and click on the Link it provides, I get Access Denied. The link looks like this:
https://s3.eu-central-1.amazonaws.com/[bucket-name]/images/36d03456fcfaa06061f.jpg
Why is it still unavailable despite setting the bucket's permissions to public?
You either need to set Object Level Permissions on each object that you want to be available to the internet as Read Object.
or, you can use Bucket Policies to make this more widely permissioned, and not worry about resetting the permissions on each upload:
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::www.example.com/*"
}
]
}

Prevent S3 user from posting to public buckets?

Suppose a public bucket exists that has a very similar name to my private bucket. I want to prevent a user from misspelling the private bucket and accidentally posting sensitive data to the public.
I understand that it would be best practice to make the bucket name as unique as possible.
Clarification: I want to prevent a user from posting to ANY public S3 bucket
Public Buckets are very rare. In fact, they are highly discouraged from a security perspective and also from a cost perspective -- somebody could upload illegal files and use it for file sharing, and the bucket owner would pay for it!
I would normally say that the chance of somebody being able to successfully upload to a random bucket is practically zero, but I suspect you are thinking of a case where an evil party might create a similarly-named bucket in the hope of collecting confidential data (similar to domain-name camping).
In that case, you can create a Deny policy on the user to prohibit access to ALL S3 buckets, except for the ones you specifically nominate:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Allow",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::good-bucket1",
"arn:aws:s3:::good-bucket2"
]
},
{
"Sid": "NotOthers",
"Effect": "Deny",
"Action": [
"s3:*"
],
"NotResource": [
"arn:aws:s3:::good-bucket1",
"arn:aws:s3:::good-bucket2" ]
}
]
}
This will work because the Deny against the IAM User will override any Allow in a Bucket Policy. The only downside is that you will need to specifically list the buckets you wish to include/exclude because there is no way to specify that rules apply to "a public bucket".
You have no control over the other bucket, so you can't prevent this happening.
To respond to it, I suppose you could query that bucket periodically, assuming it's publicly readable, in search of content that you think should have been uploaded to your bucket though it's not clear what you would do at that point.
Alternatively, provide your users with an upload page (maybe statically-hosted in your S3 bucket) and ask your users to use that page to initiate uploads (via POST or AWS S3 JavaScript SDK) so users do not have to type in a bucket name and hence cannot accidentally target the wrong bucket.

S3 Bucket Still Public Despite CloudFront Origin Identity Access Policy

I have followed the documentation on setting up a CloudFront (CF) web distribution to serve private content from my s3 bucket, but despite adjusting the settings in my distribution to do so, my s3 bucket files are still accessible via s3.amazonaws.com/bucket-name/file-name.ext. I was curious why this is still occurring because when I created a CF Origin Access Identity, I selected Yes, Update Bucket Policy, which I thought would take care of closing off the read access via my s3 bucket url, but it hasn't. Did I miss an adjustment that should be make? I assumed that settings I make on CF should adjust my s3 bucket and make it not accessible via GET requests.
Here is my s3 Bucket Policy:
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity *My-Key-ID*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket-name/*"
}
]
}
However, I noticed permissions on the individual files, but wasn't sure what they were related to.
Here are my CF settings:
Distribution:
Origin: (On initial identity creation I picked "Yes, Update Bucket Policy")
Behavior (Top Half):
Behavior (Bottom Half):
The bucket policy and object ACLs work together.
Anything allowed by either policy or object ACL is still allowed... except when explicitly denied by the bucket policy.
Your policy allows downloads through CloudFront.
Your object ACLs allow "Everyone" to "open/download" them, thus, anonymous direct access to objects in the bucket will still be allowed.
The most correct solution is to modify the object ACLs to remove the ability for "Everyone" to "open/download," which is clearly not correct if you do not want the objects to be accessible from S3 by anonymous users. In the console, click the × on that "Everyone" entry for an object, and click Save. You should find that this solves the problem.
Future objects should not be uploaded as publicly-readable.
This could also be accomplished using a custom bucket policy to override the object ACLs, but this is an advanced configuration that will break your ability to manipulate objects in the console if done incorrectly and will unnecessarily complicate things.