Amazon AWS S3 bucket anonymous upload using curl - amazon-web-services

I'm trying to set up an S3 bucket to accept anonymous uploads while allowing the bucket owner full rights and preventing public read access. Following the code from here I've set up the bucket policy below. I'd like to use curl to upload to the bucket, but all I'm getting is
Access Denied
Here's the bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "allow-anon-put",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::[mybucket]/uploads/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
},
{
"Sid": "deny-other-actions",
"Effect": "Deny",
"NotPrincipal": {
"AWS": "arn:aws:iam::[myid]:root"
},
"NotAction": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::[mybucket]/*"
}
]
}
And the curl POST:
curl --request PUT --upload-file "thefile.gif" -k https://[mybucket].s3.amazonaws.com/uploads/

Anonymous uploads are a bad idea, but at least this policy constraint requires that the uploader give you control of the object:
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
It's not intuitively obvious, but owning a bucket doesn't mean you own the objects. If they are not uploaded with credentials from your account, then you don't own them. You pay for them, of course, but if an object is uploaded into your bucket by another account or by the anonymous user, the only privilege you may end up with on that object is that you can delete it -- you can end up with objects you can't download or copy, just delete.
With this policy in place, the uploads have to comply with the policy, setting the object ACL to give you control:
curl ... -H 'x-amz-acl: bucket-owner-full-control'

Related

AWS account A->B->C S3 bucket policy access

In AWS Account B i have S3 bucket with the following bucket policy:
allow to put from Account A (working fine)
allow to list from Account C (working fine)
allow to get object from Account C (not working fine)
The policy is the following:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "ACCOUNT_A"
},
"Action": "s3:PutObject",
"Resource": "MYBUCKET/*"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "ACCOUNT_A"
},
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": "MYBUCKET"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "ACCOUNT_C"
},
"Action": [
"s3:ListBucket",
"s3:GetObject",
"s3:GetBucketLocation"
],
"Resource": [
"MYBUCKET/*",
"MYBUCKET"
]
}
]
}
Why from AWS Account C i can List but not GetObject ? (i do suspect it's because of the ownership: it's Account A who is the owner, but how to fix it)
Thanks,
If objects are upload to an Amazon S3 bucket from a different AWS Account, then the 'ownership' of the object will remain with the account that uploaded the object. This can be rather frustrating because the owner of the bucket can't even access the object!
There are two ways to avoid this...
Assign ownership
When uploading the object specify an Access Control List (ACL) that assigns ownership to the owner of hte bucket:
ACL='bucket-owner-full-control'
Turn off ACLs
You could Disable ACLs for your bucket - Amazon Simple Storage Service, which avoids the whole problem. In fact, this should probably be the default option for all buckets.

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 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

Undo aws s3 policy to deny all users all actions

I accidently set the s3 bucket policy to deny all actions to a bucket for all users
{
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:*",
Now I cant delete anything in the bucket or even remove the bucket. I can't do anything to the bucket anymore. I can't even remove it with cloudformation.
Is there a way to undo this or somehow remove this bucket?
To test this, I created a bucket and added this Bucket Policy:
{
"Id": "TryThis",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "NoBucket",
"Action": "s3:*",
"Effect": "Deny",
"Resource": "arn:aws:s3:::my-bucket",
"Principal": "*"
},
{
"Sid": "NoObjects",
"Action": "s3:*",
"Effect": "Deny",
"Resource": "arn:aws:s3:::my-bucket/*",
"Principal": "*"
}
]
}
Indeed, I was unable to:
List contents
Upload objects
Edit the Bucket Policy
However, I was able to use the Delete Bucket command in the AWS Management Console.
I then repeated the experiment and logged in using my Root Credentials. I was then able to delete the Bucket Policy and restore all functionality to the bucket. Root credentials have full access to an AWS account.

Bucket policy apply to objects not owned by me? (public bucket?)

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.