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/*".
Related
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/*"
]
}
]
}
I have a s3 bucket which does not have public access. I have a bucket policy but it was automatically generated when I connected a CDN to the bucket for a origin access Identity.
But thats all the policy has.
Bucket polices are dicks for me. Im wondering if this is in fact the problem or if it may be something else.
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::shofi-mod/*"
}
]
}
for comparison here is the bucket policy of my other bucket that does have public access. I am looking at the two for clues of what it is I should do
{
"Version": "2012-10-17",
"Id": "",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam:::user/shofi-stuff-bucket-user"
},
"Action": [
"s3:ListBucket",
"s3:ListBucketVersions",
"s3:GetBucketLocation",
"s3:Get*",
"s3:Put*"
],
"Resource": "arn:aws:s3:::shofi-stuff"
}
]
}
thank you so much kings
There's a few topics here.
The first bucket policy you have shown simply grants access to CloudFront via an Allow policy. It would not interfere with the pre-signed URL.
The second bucket policy (while not being directly relevant to your question) has an error in it. When using GetObject and PutObject, access must be granted to the contents of the bucket, no the bucket itself. (Whereas ListBucket does apply to the bucket.)
Therefore, the Resource should grant access to the bucket and the contents of the bucket:
"Resource": ["arn:aws:s3:::shofi-stuff", "arn:aws:s3:::shofi-stuff/*"]
As to why your pre-signed URL is not working, it would either be due to:
The underlying credentials (IAM User, IAM Role) that was used to generate the pre-signed URL does not have permission to perform the upload (perhaps due to a similar Resource problem), or
The pre-signed URL is being incorrectly generated
I am trying to create a bucket policy that allows the whole account access to upload objects, but limit a specific folder to a specific file ext, for example:
arn:aws:s3:::DOC-EXAMPLE-BUCKET/prefixname/*.jpg
However, after following the below example, it seems this is either only possible at a bucket level, or it restricts uploading specifically to the resource specified.
Example:
Restricting file types on amazon s3 bucket with a policy
My bucket policy looks like this:
{
"Version": "2012-10-17",
"Id": "Policy1464968545158",
"Statement": [
{
"Sid": "Stmt1464968483619",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:root"
},
"Action": "s3:PutObject",
"Resource": [
"arn:aws:s3:::DOC-EXAMPLE-BUCKET/folder/*.csv"
]
},
{
"Sid": "Stmt1464968483619",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"NotResource": [
"arn:aws:s3:::DOC-EXAMPLE-BUCKET/folder/*.csv"
]
}
]
}
Now with the above policy, it limits only uploads to that specific prefix.
I have tried using this in conjunction with a IAM policy, but the DENY statement pretty much over rides it.
I have also tried to leave out the deny statement and then use an IAM policy to grant access to the bucket and the resources, but my IAM user is still able to upload all extension types to all the different prefixes.
Has anyone been able to get this working at an account level, and not a user level?
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)/*"
}
]
}
I have configured my S3 bucket with Bucket Policy that looks like this
{
"Version": "2012-10-17",
"Id": "Policy100000000000",
"Statement": [
{
"Sid": "Stmt1463490591045",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucketname/*"
},
{
"Sid": "Stmt1463490591012",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::012345678900:user/user1",
"arn:aws:iam::012345678900:user/user2"
]
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::bucketname"
},
{
"Sid": "Stmt1463490660089",
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::012345678900:user/user1",
"arn:aws:iam::012345678900:user/user2"
]
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucketname/*.xml"
}
]
}
The goal is to allow access to xml files in the bucket root to the selected users only. The rule doesn't seem to be working, since I get access denied
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>DE3DB1FF18B53997</RequestId><HostId>Iy+RnfkFKygJWkSTI0dXjssFsGFP2MydZZi/R5KBw5M8mZnfClt6HMOKJvAwy7sJgSx9BJQ3DbN=</HostId></Error>
I've tried fetching the xml files with AWS Node.js and Python SDKs and with aws-cli. I keep getting the same access denied message.
The AWS documentation regarding Bucket Policies is quite scattered around and has not provided me with a solution to the problem. There's very little documentation at all about using notPrincipal in the policy.
The ListBucket permission works all right, which means that the problem is specific to the rule, not the aim users.
The goal is to allow access to xml files in the bucket root to the selected users only
As per current documentation, s3 do not support file listing resource per postfix/filetype. It only support with prefix, so you would need to put a star without .xml at the end (which allow to access all objects at the folder layer), then you could implement logic to your app if you would allow to access the file or not.
For the bucket policy, by default, s3 policy would give access to user from the account (where the bucket created), as long as the IAM policy have the permission to do so. This is defined from ACL (Access Control List), go to S3 > Permission > Access Control List to check it out.[ AWS S3 ACL docs ]. So the first 2 statement might not be necessary in the statements. For the last statement, this might work but need an additional assumed-role ARN which will vary depending on what is defined for the role session name.
It is recommended to not use the NotPrincipal, and instead use the Condition key at the statement. Put the roleId as the userId at the StringNotLike statement to ignore the deny statement for the particular roleId. Also include the account number at the userId. Example as follows.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::MyExampleBucket",
"arn:aws:s3:::MyExampleBucket/*"
],
"Condition": {
"StringNotLike": {
"aws:userId": [
"ROLE_ID_HERE:*",
"ACCOUNT_NUMBER_HERE"
]
}
}
}
]
}
Check out on this AWS blog for more info:
https://aws.amazon.com/blogs/security/how-to-restrict-amazon-s3-bucket-access-to-a-specific-iam-role/
Your last deny policy simply doesn't talk about what should happen (allow or deny) to the requests with principal user1 or user2. When you send an s3 request as user1 or user2, the bucket policy won't have any effect (since it doesn't have any rule matching the principal user1 or user2 w.r.t the given action and the given resource).
The goal is to allow access to xml files in the bucket root to the selected users only
In this situation, you can mention a rule for explicitly allowing those users the access to your xml files.
{
"Sid": "Stmt1463490660089",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::012345678900:user/user1",
"arn:aws:iam::012345678900:user/user2"
]
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucketname/*.xml"
}