S3 - Revoking "full_control" permission from owned object - amazon-web-services

While writing S3 server implementation, ran into question I can't really find answer anywhere.
For example I'm the bucket owner, and as well owner of uploaded object.
In case I revoke "full_control" permission from object owner (myself), will I be able to access and modify that object?
What's the expected behaviour in following example:
s3cmd setacl --acl-grant full_control:ownerID s3://bucket/object
s3cmd setacl --acl-revoke full_control:ownerID s3://bucket/object
s3cmd setacl --acl-grant read:ownerID s3://bucket/object
Thanks

So there's the official answer from AWS support:
The short answer for that question would be yes, the bucket/object
owner has permission to read and update the bucket/object ACL,
provided that there is no bucket policy attached that explicitly
removes these permissions from the owner. For example, the following
policy would prevent the owner from doing anything on the bucket,
including changing the bucket's ACL:
{
"Id": "Policy1531126735810",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Example bucket policy",
"Action": "s3:*",
"Effect": "Deny",
"Resource": "arn:aws:s3:::<bucket>",
"Principal": "*"
}
]
}
However, as root (bucket owner) you'd still have permission to delete
that policy, which would then restore your permissions as bucket owner
to update the ACL.
By default, all S3 resources, buckets, objects and subresources, are
private; only the resource owner, which is the AWS account that
created it, can access the resource[1]. As the resource owner (AWS
account), you can optionally grant permission to other users by
attaching an access policy to the users.
Example: let's say you created an IAM user called -S3User1-, and gave
it permission to create buckets in S3 and update its ACLs. The user in
question then goes ahead and create a bucket and name it
"s3user1-bucket". After that, he goes further and remove List objects,
Write objects, Read bucket permission and Write bucket permissions
from the root account on the ACL section. At this point, if you log in
as root and attempt to read the objects in that bucket, an "Access
Denied" error will be thrown. However, as root you'll be able to go to
the "Permissions" section of the bucket and add these permissions
back.

These days it is recommended to use the official AWS Command-Line Interface (CLI) rather than s3cmd.
You should typically avoid using object-level permissions to control access. It is best to make them all "bucket-owner full control" and then use Bucket Policies to grant access to the bucket or a path.
If you wish to provide per-object access, it is recommended to use Amazon S3 pre-signed URLs, which give time-limited access to a private object. Once the time expires, the URL no longer works. Your application would be responsible for determining whether a user is permitted to access an object, and then generates the pre-signed URL (eg as a link or href on an HTML page).

Related

How do you allow granting public read access to objects uploaded to AWS S3?

I have created a policy that allows access to a single S3 bucket in my account. I then created a group that has only this policy and a user that is part of that group.
The user can view, delete and upload files to the bucket, as expected. However, the user does not seem to be able to grant public read access to uploaded files.
When the Grant public read access to this object(s) option is selected, the upload fails.
The bucket is hosting a static website and I want to allow the frontend developer to upload files and make them public.
The policy for the user role is below:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": "arn:aws:s3:::my-bucket"
},
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
This is what happens when the IAM user tries to grant public access to the uploaded file:
The proxy error seems unrelated, but essentially the upload is stuck and nothing happens. If they don't select the Grant public access option, the upload goes through immediately (despite the proxy error showing up as well).
To reproduce your situation, I did the following:
Created a new Amazon S3 bucket with default settings (Block Public Access = On)
Created an IAM User (with no policies attached)
Created an IAM Group (with no policies attached)
Added the IAM User to the IAM Group
Attached your policy (from the Question) to the IAM Group (updating the bucket name) as an inline policy
Logged into the Amazon S3 management console as the new IAM User
At this point, the user received an Access Denied error because they were not permitted to list all Amazon S3 buckets. Thus, the console was not usable.
Instead, I ran this AWS CLI command:
aws s3 cp foo.txt s3://new-bucket/ --acl public-read
The result was:
An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
However, the operation succeeded with:
aws s3 cp foo.txt s3://new-bucket/
This means that the --acl is the component that was denied.
I then went to Block Public Access for the bucket and turned OFF the option called "Block public access to buckets and objects granted through new access control lists (ACLs)". My settings were:
I then ran this command again:
aws s3 cp foo.txt s3://new-bucket/ --acl public-read
It worked!
To verify this, I went back into Block Public Access and turned ON all options (via the top checkbox). I re-ran the command and it was Access Denied again, confirming that the cause was the Block Public Access setting.
Bottom line: Turn off the first Block Public Access setting.
You can do it through AWS CLI Update object's ACL
Option 1:
object that's already stored on Amazon S3, you can run this command to update the ACL for public read access:
aws s3api put-object-acl --bucket <<S3 Bucket Name>> --key <<object>> --acl public-read
Option 2:
Run this command to grant full control of the object to the AWS account owner and read access to everyone else:
aws s3api put-object-acl --bucket <<S3 Bucket Name>> --key <<object>> --grant-full-control emailaddress=<<Accountowneremail#emaildomain.com>> --grant-read uri=http://acs.amazonaws.com/groups/global/AllUsers
I found that certain actions (like renaming an object) will fail when executed from the console (but will succeed from the CLI!) when ListAllMyBuckets is not granted for all s3 resources. Adding the following to the IAM policy resolved the issue:
{
"Sid": "AccessS3Console",
"Action": [
"s3:ListAllMyBuckets"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::*"
}
Some of the actions I tested that failed from the console but succeeded from CLI:
Renaming an object. The console displays "Error - Failed to rename the file to ". Workaround: deleting and re-uploading the object with a new name.
Uploading an object with "Grant public read access to this object(s)". The console's status bar shows that the operation is stuck in "in progress". Workaround: Uploading the object without granting public read access, and then right clicking on it and selecting "Make public".
I experienced these issues after following the instructions here
https://aws.amazon.com/premiumsupport/knowledge-center/s3-console-access-certain-bucket/ which describe how to restrict access to a single bucket (and preventing seeing the full list of buckets in the account). The post didn't mention the caveats.
To limit a user's Amazon S3 console access to only a certain bucket or
folder (prefix), change the following in the user's AWS Identity and
Access Management (IAM) permissions:
Remove permission to the s3:ListAllMyBuckets action.
Add permission to s3:ListBucket only for the bucket or folder that you want the user to access.
Note: To allow the user to upload and download objects from the bucket or folder, you must also include s3:PutObject and s3:GetObject.
Warning: After you change these permissions, the user gets an Access
Denied error when they access the main Amazon S3 console. The user
must access the bucket using a direct console link to the bucket or
folder.

S3 bucket and object access

As per my understanding with out giving access, any IAM user can not access the S3 bucket/object. But in my use case I am able to access it.
Am I misunderstood the security policy in S3.
Here is my use case I have root account in AWS, say root user. And this user created two IAM users,say Admin and Test users. And root user given S3FullAccess permission to both IAM users.
Now I logged in as Admin and created one Bucket( say Test). And enabled "Block all public access ".
Now with another IAM user still I am able to access Test bucket, even though " Block all public access " enabled.
Ideally it should not right. The Test user should get access denied permission while accessing Test bucket.
Am I missing anything, any help would be highly appreciated
Thanks
AWS learner
The "block all public access" to the bucket is referring to outside your organization, not with the IAM users.
In other words, if your bucket is accessible to the public, then anyone who has access to the objects S3 URL can directly access that object.
You may restrict access to the bucket by using a bucket policy, but it would make more sense to remove the S3FullAdminAccess from the test user in IAM.
And root user given S3FullAccess permission to both IAM users
This is the reason why your both the users are able to see the bucket as they have the below policy attached with the user :
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
You remove this policy from the user and you'll see below error :

AWS S3, can not add bucket policy, get "Acess Denied" error

I have read everything I can read on the Internet or the official documents, but this error is so awkward.
I want to add following policy on to my bucket:
{ "Version":"2012-10-17", "Statement":[
{
"Sid":"AddPerm",
"Effect":"Allow",
"Principal": "*",
"Action":["s3:GetObject"],
"Resource":["arn:aws:s3:::mybucket/*"]
} ]
}
however, the only thing I can get is access denied:
I've tried to set this, but it did not work:
enter image description here
What's more, I tried to add bucket policy on my friend account, and it works, the only difference between these two accounts is that my account has an elastic beanstalk(I do not know whether this would affect the result), so please tell me what should I do?
Check what is the policy on that bucket and what is the policy the user under which you are logged in have. For being able to to change bucket policy you need the PutBucketPolicy permission. Keep in mind that Deny anywhere will block you from doing the specified action.
The fix would be adding s3:PutBucketPolicy to yourself and then you should be able to change the s3 bucket permissions. The user policy and the bucket policy on the same account should be "a union" of both policies, but it would be "an intersection" if you are accessing another account - but it seems that you are changing a bucket in your account, so you should be fine with that.
If you cannot change your user IAM policy or you accidentally put Deny on the bucket you will have to log in as the account root and try to fix that this way.
Also, make sure that making all objects in your bucket public is what you plan to do. You allow only GetObject, so if this should be some statically hosted content, this should be fine.

S3 bucket policy vs access control list

On AWS website, it suggests using the following bucket policy to make the S3 bucket public:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::example-bucket/*"
]
}
]
}
What's the difference between that and just setting it through the Access Control List?
Bottom line: 1) Access Control Lists (ACLs) are legacy (but not deprecated), 2) bucket/IAM policies are recommended by AWS, and 3) ACLs give control over buckets AND objects, policies are only at the bucket level.
Decide which to use by considering the following: (As noted below by John Hanley, more than one type could apply and the most restrictive/least privilege permission will apply.)
Use S3 bucket policies if you want to:
Control access in S3 environment
Know who can access a bucket
Stay under 20kb policy size max
Use IAM policies if you want to:
Control access in IAM environment, for potentially more than just buckets
Manage very large numbers of buckets
Know what a user can do in AWS
Stay under 2-10kb policy size max, depending if user/group/role
Use ACLs if you want to:
Control access to buckets and objects
Exceed 20kb policy size max
Continue using ACLs and you're happy with them
https://aws.amazon.com/blogs/security/iam-policies-and-bucket-policies-and-acls-oh-my-controlling-access-to-s3-resources/
If you want to implement fine grained control over individual objects in your bucket use ACLs. If you want to implement global control, such as making an entire bucket public, use policies.
ACLs were the first authorization mechanism in S3. Bucket policies are the newer method, and the method used for almost all AWS services. Policies can implement very complex rules and permissions, ACLs are simplistic (they have ALLOW but no DENY). To manage S3 you need a solid understanding of both.
The real complication happens when you implement both ACLs and policies. The end permission set will be the least privilege union of both.
AWS has outlined the specific use cases for the different access policy options here
They lay out...
When to Use an Object ACL
when objects are not owned by bucket owner
permissions vary by object
When to Use a Bucket ACL
to grant write permission to the Amazon S3 Log Delivery group to write access log objects to your bucket
When to Use a Bucket Policy
to manage cross-account permissions for all Amazon S3 permissions (ACLs can only do read, write, read ACL, write ACL, and "full control" - all of the previous permissions)
When to Use a User Policy
if you want to manage permissions individually by attaching policies to users (or user groups) rather than at the bucket level using a Bucket Policy

How to secure an S3 bucket to an Instance's Role?

Using cloudformation I have launched an EC2 instance with a role that has an S3 policy which looks like the following
{"Statement":[{"Action":"s3:*","Resource":"*","Effect":"Allow"}]}
In S3 the bucket policy is like so
{
"Version": "2012-10-17",
"Id": "MyPolicy",
"Statement": [
{
"Sid": "ReadAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456678:role/Production-WebRole-1G48DN4VC8840"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::web-deploy/*"
}
]
}
When I login to the instance and attempt to curl any object I upload into the bucket (without acl modifications) I receive and Unauthorized 403 error.
Is this the correct way to restrict access to a bucket to only instances launched with a specific role?
The EC2 instance role is more than sufficient to put/read to any of your S3 buckets, but you need to use the instance role, which is not done automatically by curl.
You should use for example aws s3 cp <local source> s3://<bucket>/<key>, which will automatically used the instance role.
There are three ways to grant access to an object in Amazon S3:
Object ACL: Specific objects can be marked as "Public", so anyone can access them.
Bucket Policy: A policy placed on a bucket to determine what access to Allow/Deny, either publicly or to specific Users.
IAM Policy: A policy placed on a User, Group or Role, granting them access to an AWS resource such as an Amazon S3 bucket.
If any of these policies grant access, the user can access the object(s) in Amazon S3. One exception is if there is a Deny policy, which overrides an Allow policy.
Role on the Amazon EC2 instance
You have granted this role to the Amazon EC2 instance:
{"Statement":[{"Action":"s3:*","Resource":"*","Effect":"Allow"}]}
This will provide credentials to the instance that can be accessed by the AWS Command-Line Interface (CLI) or any application using the AWS SDK. They will have unlimited access to Amazon S3 unless there is also a Deny policy that otherwise restricts access.
If anything, that policy is granting too much permission. It is allowing an application on that instance to do anything it wants to your Amazon S3 storage, including deleting it all! It is better to assign least privilege, only giving permission for what the applications need to do.
Amazon S3 Bucket Policy
You have also created a Bucket Policy, which allows anything that has assumed the Production-WebRole-1G48DN4VC8840 role to retrieve the contents of the web-deploy bucket.
It doesn't matter what specific permissions the role itself has -- this policy means that merely using the role to access the web-deploy bucket will allow it to read all files. Therefore, this policy alone would be sufficient to your requirement of granting bucket access to instances using the Role -- you do not also require the policy within the role itself.
So, why can't you access the content? It is because using a straight CURL does not identify your role/user. Amazon S3 receives the request and treats it as anonymous, thereby not granting access.
Try accessing the data via the CLI or programmatically via an SDK call. For example, this CLI command would download an object:
aws s3 cp s3://web-deploy/foo.txt foo.txt
The CLI will automatically grab credentials related to your role, allowing access to the objects.