AWS S3 sharing access to static website - 403 access denied - amazon-web-services

I've configured my bucket policy (for a static website hosted on an S3 bucket) so that another account can perform actions on this bucket. The policy looks something like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mybucket.com/*"
},
{
"Sid": "Example permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::00000000000:user/username"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::mybucket.com"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::000000000000:user/username"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::mybucket.com/*"
}
]
}
The first object in "Statement" specifies that this bucket should be readable by the public, so that anyone can access the site (I am using Route 53 as well).
The second account is able to upload files to the bucket, however once he uploads a file, then access is restricted to that file, i.e. if he uploads index.html to the top-level directory of the bucket, then navigating to the website will produce a 403 access denied error.
I have looked into IAM roles, which I think may be related but would appreciate any help with this.

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

Restrict public read to server access logging folder in S3

I have a public S3 bucket with read-only access. Then I enabled server access logging to the current bucket but I'm afraid that other users could view the access log anonymously for their own use so I put a deny policy to the /access-logs folder. However, server access logging now is not working since I put Deny effect to the statement as documented in here. Is there any method to enable logging while restrict the access folder only to the bucket owner?
{
"Version": "2012-10-17",
"Id": "S3-Console-Auto-Gen-Policy-1234567",
"Statement": [
{
"Sid": "S3PolicyStmt-DO-NOT-MODIFY-1234567",
"Effect": "Allow",
"Principal": {
"Service": "logging.s3.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::example-bucket/*"
},
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example-bucket/*"
},
{
"Sid": "RestrictAccessLOgs",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example-bucket/access-logs/*"
}
]
}
You should not put the logs in the same bucket as Coward Anon user said. You can use one bucket to store logs from many different buckets but one should not store logs from itself.
Your target bucket should not have server access logging enabled. You can have logs delivered to any bucket that you own that is in the same Region as the source bucket, including the source bucket itself. However, this would cause an infinite loop of logs and is not recommended. For simpler log management, we recommend that you save access logs in a different bucket.
It's much simpler to do it and set your logs bucket to private (default).
Not recommended, this is just to get you to know about NotPrincipal
{
"Sid": "RestrictAccessLOgs",
"Effect": "Deny",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example-bucket/access-logs/*",
"NotPrincipal": {
"Service": ["logging.s3.amazonaws.com"]
}
}

Allow S3 bucket operations based on EC2 role

Our EC2s are secured using IAM roles. When trying to run an AWS console command such as aws s3 cp I am seeing:
fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden
If allowed based on specific users that are given keys, there are no issues. This just isn't working with roles.
Here is the bucket ACL:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Public",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
},
{
"Sid": "Devs",
"Effect": "Deny",
"NotPrincipal": {
"AWS": "arn:aws:iam::1234567890:user/DevUser"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket/something-privileged/*"
},
{
"Sid": "EC2s",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1234567890:role/EC2Role"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket/something-privileged/*"
},
]
}
As you can see, we want the public to generally be able to fetch objects that we link to. This works.
We want devs to be able to access a specific hidden folder in the bucket using their AWS keys. This works.
We want EC2s to be able to run aws-cli commands on that same hidden folder using only the assigned security role. This does not work.
I also tried "Effect": "Deny", "NotPrincipal": { ... } on the EC2 statement but that didn't work either.
What's wrong with this ACL?
You have a Deny statement in this where the principal is not that specific IAM user. In any AWS privilege a deny will always override an allow which is the scenario happening here.
To allow this here you will need to include the IAM role arn in the NotPrincipal statement as well. This would look like the below statement.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Public",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
},
{
"Sid": "Devs",
"Effect": "Deny",
"NotPrincipal": {
"AWS": ["arn:aws:iam::1234567890:user/DevUser", "arn:aws:iam::1234567890:role/EC2Role"]
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket/something-privileged/*"
}
]
}

403 on S3 bucket object in browser

I've a private bucket with OAI and CloudFront. When I upload an item to the bucket I can visit it using the CloudFront URL but not via the S3 url:
My policy looks like this
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "AllowCloudFrontRead",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity xxx"
},
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::xxx/*"
}
]
}
My IAM user has the permission to upload and get from the bucket.
Now I want that my user (or my account) can visit the S3 URL (not the CloudFront URL) to access the object in the bucket without the need to make the bucket public.
How can I do this?
I tried to update the bucket policy like this but it didn't work.
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "AllowCloudFrontRead",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity xxx"
},
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::xxx/*"
},
{
"Sid": "AllowPolicyRead",
"Effect": "Allow",
"Principal": {
"AWS": "xxxxx"
},
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::xxx/*"
}
]
}
From the CLI my user can get and upload objects.
IAM or bucket policies give you API level access to S3. It is not possible to download S3 files without making buckets public.

S3 bucket access is locked

Its found that the S3 bucket in our account got applied with wrong bucket policy, now the access is denied for all users including root user
"bucketName": "somebucket",
"bucketPolicy": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt15348761457344",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::dhasg",
"Principal": "*"
},
{
"Sid": "Stmt153478299578",
"Action": "s3:*",
"Effect": "Deny",
"Resource": "arn:aws:s3:::somebucket",
"Principal": "*"
}
]
We are not able to change the permission through AWS console and CLI and not able to delete the bucket also. How to fix it?
You should be able to edit the bucket policy as root. You will not be able to delete the bucket, even as root until you modify the policy.