Static web hosting on AWS S3 giving me "403 permission denied" - amazon-web-services

I will appreciate if anyone can point me out where I'm doing wrong. see below steps
I have a domain name in route53.
Based on the domain name, I have created a bucket name ( for sake of my question lets stick to bucket and domain name as abc.nl)
Created the bucket, without changing any default provided check-list.
Clicked the bucket(abc.nl) and added below "bucket policy"
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1234567:user/usrname"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::abc.nl/*"
}
]
}
I have provided my username policy of AmazonS3FullAccess in IAM.
My Block public access (account settings) also unchanged.
Now I uploaded my all static files to the bucket(abc.nl).
In properties tab, I have added index.html under static website hosting block.
Now, as per the manual, I should able to click the link and access the page.
But for some reason, it's throwing me 403 access forbidden error.
In my understanding, by simply adding bucket policy you turn on public access. But for me, I don't see "public" tag. So, don't know what's going on. (My understanding could be wrong, hence this post.)
In case you are wondering which manual, I'm following, https://docs.aws.amazon.com/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.htmlhow to host static web site.
Anyway, anyone points me out, where I'm doing wrong and which options should I choose from the permissions for the bucket? I could be missing out some lines.
PS: I have created and deleted the same bucket multiple times, just to start fresh every time.

The Principal value of your bucket policy is wrong. Copied from the Example: Setting up a Static Website Using a Custom Domain that you have linked to:
To grant public read access, attach the following bucket policy to the example.com bucket, substituting the name of your bucket for example.com.
{
"Version":"2012-10-17",
"Statement":[{
"Sid":"PublicReadGetObject",
"Effect":"Allow",
"Principal": "*",
"Action":["s3:GetObject"],
"Resource":["arn:aws:s3:::example.com/*"]
}]
}

To make the bucket public (= everyone), you need to set * as principal in your bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::abc.nl/*"
}
]
}
Please also check that you don't have Block public access settings on the bucket because it will prevent you from making the bucket public.

Follow the below Steps 100% working.
Under Buckets, choose the name of your bucket.
Choose Permissions.
Under Bucket Policy, choose Edit.
To grant public read access to your website, copy the following bucket policy, and paste it into the Bucket policy editor.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::**YOUR-BUCKET-NAME**/*"
]
}
]
}
NOTE: AWS documentation Link

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::pasteyourbucketname(copy&pasteARNName)/*"
}
]
}

Related

S3 Policy Help - Full access for IAM user. Public read only access for single folder

I have an IAM user created with a policy for my bucket. With "public block access" enabled I can interact with the bucket as expected through this user.
Now I need to make a single public read-only folder using bucket policies, but I am not having any luck. I created the below policy which should
Disable all access to all principles
Enable all access for my IAM user
Enable read-only access to specific folders for all users.
{
"Id": "Policy1676746531922",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1676745894018",
"Action": "s3:*",
"Effect": "Deny",
"Resource": "arn:aws:s3:::bucket/*",
"Principal": "*"
},
{
"Sid": "Stmt1676746261470",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::bucket/*",
"Principal": {
"AWS": [
"arn:aws:iam::000000000:user/bucket-user"
]
}
},
{
"Sid": "Stmt1676746523001",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::bucket/read-only-folder",
"Principal": "*"
}
]
}
I guess you cannot layer up access in this way, but I am unsure how to construct what I need. If I go with a single read policy to open up one folder, I still seem to be able to access all other folders publically too:
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "AllowPublicRead",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket-name/public/*"
}
]
}
I can access "/public" but can still access "/private" too.
I need a way first to lock down the entire bucket and then open up the folders I want to provide access for?
Your policy is failing because Deny always overrides an Allow.
The first statement in the policy will Deny access to the bucket for everyone (including you!).
Your second policy on arn:aws:s3:::bucket-name/public/* is the correct way to go. It will only grant anonymous access to that particular folder.
If you are able to access other folders, then either there are other policies that exist, or you are using "authenticated access" using your own AWS credentials. Make sure when you test it that you are putting a URL into a web browser that simply looks like: https://bucket-name.ap-southeast-2.s3.amazonaws.com/foo.txt

How to set access level as "Public" for all files uploading to an S3 bucket?

I have created an S3 bucket and also an API through the AWS API Gateway to upload images to the bucket. The problem is, when I upload an image, to view that image I need to update the Access control list (ACL) to Public for each image separately. Even though I set everything to the public in the bucket permissions, still I have to update the ACL in each image to access them. How can I set the access level to "Public" for the whole bucket once?
This is my bucket permissions:
Access: Public
Block all public access: Off
Bucket policy:
{
"Version": "2012-10-17",
"Id": "Policy1647249671911",
"Statement": [
{
"Sid": "Stmt1647249649218",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::mybucketname"
}
]
}
Access control list (ACL):
Your current policy is highly insecure and allows anyone to do pretty much anything with your bucket, including changing it policy or deleting it.
The correct bucket policy for public, read-only access is:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": [
"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
]
}
]
}

How to make a public bucket only accessible from cloudfront without OAI?

I have a bucket that contains some images. The bucket is publicly accessible using the following policy.
{
"Version": "2008-10-17",
"Id": "s3BucketPolicy",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::Bucketname/*"
}
]
}
Also I have a cloudfront distribution that points to the same bucket. My problem now is that my file is accessible from both cloudfront link and bucket link.
CloudfrontLink: www.xxxxxx.xxxx/xxxx
BucketLink: www.bucketname/xxx
My question how can i make my bucket publicly accessible using cloudfront only. I don't want signed urls or cookies. I want any my anyone with cloudfrontlink to be able to access the image and prevent anyone with bucketlink from accessing the image.
Change the S3 bucket policy principal to the OAI of the CloudFront Distribution. For example:
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ABCDABCDABCDAB"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mybucket/*"
}
]
}
This will prevent access to the bucket contents outside of CloudFront. You don't need signed URLS here. See the documentation for more details.

Remove AWS S3 bucket having Read by Everyone permission through Bucket policy

Suppose I have an S3 bucket that has "Everyone Read" permission. Bucket is not public. Means anyone can access objects by typing its url in the browser. Now I want to remove this access from URL thing in browser. One option is to go to each images and remove "Read" from "Everyone" section. But since there are huge amount of images so this is not feasible.
So can I put such bucket policy which allows access only from one IAM user and not from browser thing? I tried adding such bucket policy that allow access to all resources for only specific user but still images are accessible from browsing through URL. Any thoughts?
Edit: Adding policy that I tried
{
"Id": "Policy1",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::test-bucket-public-issue",
"Principal": {
"AWS": [
"arn:aws:iam::AccounId:user/Username"
]
}
}
]
}
Ok #Himanshu Mohan I will explain you what i have done. I have created a S3 bucket and then i added the below bucket policy
{
"Version": "2012-10-17",
"Id": "Policy1534419239074",
"Statement": [
{
"Sid": "Stmt1534419237657",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::xxx-xxx-test/*"
}
]
}
While adding this policy the bucket will automatically public
Then i have uploaded an image as what you referred and i was able to access the same image via browser.
Now I changed the policy back to as what you said
Now i was not able to access the image, will show the access denied xml response. The only difference i see is i have added the /* after the bucket name "Resource": "arn:aws:s3:::xxx-xxx-test/*".

How to set S3 bucket policy to (mostly) private when object acl is public?

I can't work out how to set my bucket policy to achieve what I want. Any help would be much appreciated! My desired rules are:
users in my account have access via user policies, so shouldn't need access specifically granted to them
anonymous users (or anyone outside my AWS account) should have no access, except:
one folder /temp_public should have a public GetObject (i.e. if you know the URL you can get the file)
these policies should override the object ACL on the files in the bucket, as the object ACLs are sometimes set to public read.
The reason for creating the bucket policy is that many of the objects in the bucket have a public read ACL (inadvertently set when the files were uploaded, but could also happen in future so I want to override the object ACL with the bucket ACL).
Ignoring the temp_public folder, I hoped I could just do this:
{
"Version": "2008-10-17",
"Id": "Policy123456789",
"Statement": [
{
"Sid": "Stmt1",
"Effect": "Deny",
"NotPrincipal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket-name/*"
}
]
}
(where 123456789012 is my AWS account number), but I get access denied for all users with that bucket policy. I guess the NotPrincipal isn't working in this case?
thanks for any suggestions!
Rory
UPDATE: cross-posted here on AWS forums, and answered!
Many thanks to IP from AWS Forums for this answer, which I've confirmed is working for me:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::BucketName/temp_public/*"
}
]
}
This statement will give anyone Read access to objects inside temp_public folder, regardless ACLs on those files.
To override the public access on all other files, you should provide a +Deny+-type statement. The explicit Deny overrides any Allow access, so you must exclude already given permissions. so use NotResource as an exclusion mask (NOT FINAL YET, read below):
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"NotResource": "arn:aws:s3:::BucketName/temp_public/*"
}
However, this will deny access to ALL users including your account too, because principal is set to "*". Therefore, you must exclude your account from this Deny (STILL NOT FINAL):
{
"Effect": "Deny",
"NotPrincipal": { "AWS": "arn:aws:iam::XXXXYYYYZZZZ:root" },
"Action": "s3:GetObject",
"NotResource": "arn:aws:s3:::BucketName/temp_public/*"
}
(where XXXXYYYYZZZZ is your 12-digit AWS account Id)
There's still problem: the statement above denies access to all IAM users (except root account).
You'd like to exclude all your IAM users too, but this is tricky. For some reasons, Amazon S3 doens't support wildcards for specifying IAM users in a bucket policy. You cannot write "arn:aws:iam::XXXXYYYYZZZZ:user/*" as Principal (it gives an error: "Invalid principal in policy"). You have to specify exact user names:
{
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::XXXXYYYYZZZZ:root",
"arn:aws:iam::XXXXYYYYZZZZ:user/user1",
"arn:aws:iam::XXXXYYYYZZZZ:user/user2",
"arn:aws:iam::XXXXYYYYZZZZ:user/user3",
"arn:aws:iam::XXXXYYYYZZZZ:user/user4" ]
}
"Action": "s3:GetObject",
"NotResource": "arn:aws:s3:::BucketName/temp_public/*"
}
NB from Rory: The S3 docs suggest you can use arn:aws:iam::XXXXYYYYZZZZ:root to cover all users in the account, but that just doesn't seem to work
So the final policy will look like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::BucketName/temp_public/*"
},
{
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::XXXXYYYYZZZZ:root",
"arn:aws:iam::XXXXYYYYZZZZ:user/user1",
"arn:aws:iam::XXXXYYYYZZZZ:user/user2",
"arn:aws:iam::XXXXYYYYZZZZ:user/user3",
"arn:aws:iam::XXXXYYYYZZZZ:user/user4" ]
}
"Action": "s3:GetObject",
"NotResource": "arn:aws:s3:::BucketName/temp_public/*"
}
]
}