Bucket policy apply to objects not owned by me? (public bucket?) - amazon-web-services

First, let me link you context:
https://stackoverflow.com/a/9285074/6347501
I'm trying to create a public bucket for some app I'm writing. I have a policy to allow PUT and GET on all items in the bucket. But, as you can see from the link above, the policy simply won't apply to any items Put into the bucket that don't give me ownership.
Is there any solution? Is it actually possible to create a truly public bucket?
Ideally every object in this bucket is accessible to everyone regardless of who uploaded it.

Heres a working policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
It denies any objects that don't use the canned ACL "bucket-owner-full-access," which are also objects that would ignore our open GetObject policy.

Related

How can I allow everyone in my org to access an object uploaded by someone else?

I maintain an S3 bucket for my org that is not publicly accessible but is readable by everyone in the org. There's also a folder, sandbox, that everyone in the org can write to. I setup my S3 permissions as:
{
"Version": "2012-10-17",
"Id": "...",
"Statement": [
{
"Sid": "...",
"Effect": "Allow",
"Principal": {
"AWS": ["arn:aws:iam::1234:root"]
},
"Action": [
"s3:GetObject",
"s3:GetObjectTagging"
],
"Resource": "arn:aws:s3:::my-bucket/*"
},
{
"Sid": "...",
"Effect": "Allow",
"Principal": {
"AWS": ["arn:aws:iam::1234:root"]
},
"Action": [
"s3:GetObject",
"s3:GetObjectTagging",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::my-bucket/sandbox/*"
}
]
}
Here, 1234 is a user in my org; I have enumerated all my users here. The first Statement allows read-only access while the second gives write to only the sandbox directory. These both work, but I've found that when people in my org write to it, no one has access to read those files except the individual who wrote it.
I instructed users to copy files there using --acl bucket-owner-full-control; for example:
aws s3 cp --acl bucket-owner-full-control my_file.tsv s3://my-bucket/sandbox/
But this doesn't fix the permissions. What's the right way to make it so I effectively own all uploaded files, or at least so that everyone can read files that anyone else uploads?
This is probably unrelated, but I also tried including a condition for bucket owner:
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
I put this Condition as a sibling value to Action, Resource, etc., but when I try to save the permissions, I get the error:
Conditions do not apply to combination of actions and resources in statement
I'm sure that you asked this on the assumption that users from different AWS accounts uploading objects.
Reading the description of the bucket-owner-full-control Canned ACL in the following Controlling ownership of uploaded objects using S3 Object Ownership page, you can get that it's applicable when objects are uploaded.
Thus, create another Statement with only s3:PutObject and you can give it permission with its condition.
The policy would be as following:
{
"Version": "2012-10-17",
"Id": "...",
"Statement": [
{
"Sid": "...",
"Effect": "Allow",
"Principal": {
"AWS": ["arn:aws:iam::1234:root"]
},
"Action": [
"s3:GetObject",
"s3:GetObjectTagging"
],
"Resource": "arn:aws:s3:::my-bucket/*"
},
{
"Sid": "...",
"Effect": "Allow",
"Principal": {
"AWS": ["arn:aws:iam::1234:root"]
},
"Action": [
"s3:GetObject",
"s3:GetObjectTagging",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::my-bucket/sandbox/*"
},
{
"Sid": "...",
"Effect": "Allow",
"Principal": {
"AWS": ["arn:aws:iam::1234:root"]
},
"Action": ["s3:PutObject"],
"Resource": "arn:aws:s3:::my-bucket/sandbox/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
}
]
}
Take a look at this documentation as well.
For instance, Request syntax of GetObject cannot be applied with x-amz-acl, but putObject is applicable.
BTW, this answer above is about the issue relevant to condition, not allows all the users from different account.
So, you can grant permission to another AWS account.
How to provide cross-account access to objects that are in S3 buckets?
Bucket owner granting cross-account bucket permissions

Having trouble creating a policy in AWS

I have been tasked with an assignment to create what I believe is a bucket policy in AWS. I have uploaded a video to an S3 bucket, and I have to create a policy to limit who can view it based on their IP address. Currently I need to make it so only somebody at my home network can watch it.
I am also supposed to restrict who can watch it based on their username. The bucket is publicly viewable right now and so is the video file.
I have two policies below that I have tried and neither of them are working.
First Policy: I have tried using both my private and public IP addresses.
{
"Version": "2012-10-17",
"Id": "Policy1607205862213",
"Statement": [
{
"Sid": "Stmt1607205861134",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::internshipbucket12",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": "10.1.10.1"
}
}
}
]
}
Second Policy: Whenever I try using the arn of my bucket, it gives an error of some kind. When I put in the arn of the video file I am using, it accepts it just fine.
{
"Version": "2012-10-17",
"Id": "S3PolicyId1",
"Statement": [
{
"Sid": "IPAllow",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::DOC-EXAMPLE-BUCKET;",
"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
],
"Condition": {
"NotIpAddress": {
"aws:SourceIp": "54.240.143.0/24"
}
}
}
]
}
Amazon S3 buckets are private by default. Therefore, there is no need to 'Deny' access, since it is already denied by default. Instead, you should use an 'Allow' policy to permit access.
Turn off Block S3 Public Access (or at least the two parts that refer to Bucket Policies)
Add a policy that permits access to objects from a given IP address:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::internshipbucket12/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "54.240.143.0"
}
}
}
]
}
Note that this is granting access to a public IP address, and is only permitting GetObject, so the user will need to know the exact filename (Key) of the object they want (since it does not grant permission to list the contents of the bucket).

Amazon S3 bucket policy for referer condition on specific folder

I want to use condition of StringLike aws:Referer for a particular folder and make rest of the folder publicly accessible.
Here is my bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::bucketName/folderName/*"
]
},
{
"Sid": "",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucketName/folderName/users/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"https://example.com/*"
]
}
}
}
]
}
When I am using above policy, it is not working with first one.
Try with below policy:
{
"Sid": "",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucketName/folderName/users/*",
"Condition": {
"StringNotLike": {
"aws:Referer": [
"https://example.com/*"
]
}
}
}
The first part of your policy is granting GetObject access for anything in the folderName path of your bucket. This includes folderName/users/*.
Therefore, the second part of your policy is not being used (since the first policy is already granting access to the folderName/users/* path.
You could solve it by using different buckets, or you could convert the second policy into a Deny with StringNotLike (effectively saying that access is denied to folderName/users/* if the referer is not example.com.
Frankly, your policy looks strange because it is granting access to the entire users path hierarchy, which probably isn't what you'd want it to do. (I'm assuming you'd want to grant access only to a particular user's data based upon who is accessing your application.)
Please note that referer is not secure — it is easy to fake this value in a browser and in web-scraping softare.

AWS S3 Bucket policy public. How to make object private?

I've a bucket with GetObject available to everyone on full bucket(*). I want to make a few objects private(through Object level operation ACL), i.e. only the bucket owner should have read access to the object. I've gone through all available documentation, but couldn't find any possible way. Can anyone confirm is this possible or not?
You cannot use S3 Object ACLs because ACLs do not have a DENY.
You can modify your S3 policy to specify objects and deny access to individual items.
Example S3 Policy (notice that this policy forbids access to everyone for GetObject for two files):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mybucket/*"
},
{
"Sid": "DenyPublicReadGetObject",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::mybucket/block_this_file",
"arn:aws:s3:::mybucket/block_this_file_too"
]
}
]
}
If you want to add a condition so that certain users can still access the objects, add a condition after the Resource section like this. This condition will allow IAM users john.wayne and bob.hope to still call GetObject.
"Resource": [
"arn:aws:s3:::mybucket/block_this_file",
"arn:aws:s3:::mybucket/block_this_file_too"
],
"Condition": {
"StringNotEquals": {
"aws:username": [
"john.wayne",
"bob.hope"
]
}
}

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/*"
}
]
}