Amazon S3 access control-Who can upload files? - amazon-web-services

I have a static website created with Amazon S3. The only permissions I have set are through the bucket policy provided in Amazons tutorial:
{
"Version":"2012-10-17",
"Statement": [{
"Sid": "Allow Public Access to All Objects",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example.com/*"
}
]
}
Clearly, this policy enables the public to view any file stored on my bucket, which I want. My question is, is this policy alone enough to prevent other people from uploading files and/or hijacking my website? I wish for the public to be able to access any file on the bucket, but I want to be the only one with list, upload, and delete permissions. Is this the current behavior of my bucket, given that my bucket policy only addresses view permissions?

Have a look at this: http://docs.aws.amazon.com/IAM/latest/UserGuide/AccessPolicyLanguage_EvaluationLogic.html#policy-eval-basics
From that document:
When a request is made, the AWS service decides whether a given
request should be allowed or denied. The evaluation logic follows
these rules:
By default, all requests are denied. (In general, requests made using
the account credentials for resources in the account are always
allowed.)
An explicit allow overrides this default.
An explicit deny overrides any allows.
So as long as you don't explicitly allow other access you should be fine. I have a static site hosted on S3 and I have the same access policy.

Related

Make one S3 bucket public

Currently I have 5 S3 buckets in my account, and all of them are Block all public access -> ON and the same setting is also there for Block Public Access settings for this account -> ON.
Now I want to create a new bucket that should be public, and I don't want to change any of my existing buckets. So for the newly created bucket I have set Block all public access = OFF. But when I try to save below policy, it gives Access denied error. So I guess I have to Turn Off Block Public Access settings for this account.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Action": "s3:GetObject",
"Effect": "Allow",
"Resource": "arn:aws:s3:::MyNewImageBucketS3/*",
"Principal": "*"
}
]
}
I want to know that if I turn off account level setting, then will it affect my existing buckets?
As a second option I can configure CloudFront and serve files publicly but want to know about the public access change at the account level.
Block all public access = OFF; this setting is for individual s3 buckets provided you are doing it from bucket settings, so for that specific bucket you can turn this off and you are good to go.
If you want specific objects to be publicly accessible then this can be achieved via similar IAM policy you shared but to make this work turn on public access on that bucket and then you can apply IAM policy to allow specific objects and deny remaining.
Below image describes that if you change it in bucket setting, its going to effect on that specific bucket and the objects within bucket only
For more guidelines please check below AWS doc
https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-policy-alternatives-guidelines.html

Grant access to Amazon S3 bucket only to one IAM User

I wish to have a bucket that only one IAM user could access using the AWS Console, list its content and access object files inside it.
So, I have created the IAM user, the bucket itself, and later:
bucket policy as follow:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "statement1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::0000000:user/dave"
},
"Action": [
"s3:GetBucketLocation",
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::testbucket1234"
},
{
"Sid": "statement2",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::0000000:user/dave"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::testbucket1234/*"
}
]
}
And also a inline policy attached to my user's group, as follow:
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:*Object",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::testbucket1234/*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "*"
}
]
}
Now: I can list my buckets, access the desired bucket, list its content (so far so good). The problem is when I try to open one file object inside the bucket and I get "access denied" error. If I turn the object public, I can access it, but I can also access it using other IAM accounts, and that is not the intention. I want to access the bucket, list its contents and access objects only by usage of this specific IAM account. What am I doing wrong? How can I reach this goal? Thanks in advance.
By default, no IAM User can access any bucket. It is only by granting permissions to users that they can access resources.
However, many people tend to grant Amazon S3 permissions for all buckets, at least for Administrators. This then makes it difficult to remove permissions so that a bucket can only be accessed by one user. While it can be done with Deny policies, such policies are difficult to craft correctly.
For situations where specific data should only be accessed by one user, or a specific group of users (eg HR staff), I would recommend that you create a separate AWS Account and only grant permission to specific IAM Users or IAM Groups via a Bucket Policy (which works fine cross-account). This way, any generic policies that grant access to "all buckets" will not apply to buckets in this separate account.
Update: Accessing private objects
Expanding on what is mentioned in the comments below, a private object in Amazon S3 can be accessed by an authorized user. However, when accessing the object, it is necessary to identify who is accessing the object and their identity must be proved. This can be done in one of several ways:
In the Amazon S3 management console, use the Open command (in the Actions menu). This will open the object using a pre-signed URL that authorizes the access based upon the user who logged into the console. The same method is used for the Download option.
Using the AWS Command-Line Interface (CLI), you can download objects. The AWS CLI needs to be pre-configured with your IAM security credentials to prove your identity.
Programs using an AWS SDK can access S3 objects using their IAM security credentials. In fact, the AWS CLI is simply a Python program that uses the AWS SDK.
If you want to access the object via a URL, an application can generate an Amazon S3 pre-signed URLs. This URL includes the user's identity and a security signature that grants access to a private object for a limited period (eg 5 minutes). This method is commonly used when web applications want to grant access to a private object, such as a document or photo. The S3 management console actually uses this method when a user selects Actions/Open, so that the user can view a private object in their browser.

My AS3 Bucket Policy only applies to some Objects

I'm having a really hard time setting up my bucket policy, it looks like my bucket policy only applies to some objects in my bucket.
What I want is pretty simple: I store video files in the bucket and I want them to be exclusively downloadable from my webiste.
My approach is to block everything by default, and then add allow rules:
Give full rights to root and Alice user.
Give public access to files in my bucket from only specific referers (my websites).
Note:
I manually made all the objects 'public' and my settings for Block Public Access are all set to Off.
Can anyone see any obvious errors in my bucket policy?
I don't understand why my policy seems to only work for some files.
Thank you so much
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::MY_BUCKET/*",
"Condition": {
"StringNotLike": {
"aws:Referer": [
"https://mywebsite1.com/*",
"https://mywebsite2.com/*"
]
}
}
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::MY_BUCKET/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"https://mywebsite1.com/*",
"https://mywebsite2.com/*"
]
}
}
},
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::426873019732:root",
"arn:aws:iam::426873019732:user/alice"
]
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::MY_BUCKET",
"arn:aws:s3:::MY_BUCKET/*"
]
}
]
}
Controlling access via aws:Referer is not secure. It can be overcome quite easily. A simple web search will provide many tools that can accomplish this.
The more secure method would be:
Keep all objects in your Amazon S3 bucket private (do not "Make Public")
Do not use a Bucket Policy
Users should authenticate to your application
When a user wishes to access one of the videos, or when your application creates an HTML page that refers/embeds a video, the application should determine whether the user is entitled to access the object.
If the user is entitled to access the object, the application creates an Amazon S3 pre-signed URL, which provides time-limited access to a private object.
When the user's browser requests to retrieve the object via the pre-signed URL, Amazon S3 will verify the contents of the URL. If the URL is valid and the time limit has not expired, Amazon S3 will return the object (eg the video). If the time has expired, the contents will not be provided.
The pre-signed URL can be created in a couple of lines of code and does not require and API call back to Amazon S3.
The benefit of using pre-signed URLs is that your application determines who is entitled to view objects. For example, a user could choose to share a video with another user. Your application would permit the other user to view this shared video. It would not require any changes to IAM or bucket policies.
See: Amazon S3 pre-signed URLs
Also, if you wish to grant access to an Amazon S3 bucket to specific IAM Users (that is, users within your organization, rather than application users), it is better to grant access on the IAM User rather than via an Amazon S3 bucket. If there are many users, you can create an IAM Group that contains multiple IAM Users, and then put the policy on the IAM Group. Bucket Policies should generally be used for granting access to "everyone" rather than specific IAM Users.
In general, it is advisable to avoid using Deny policies since they can be difficult to write correctly and might inadvertently deny access to your Admin staff. It is better to limit what is being Allowed, rather than having to combine Allow and Deny.

Having trouble granting public read permissions in S3 bucket

I'm trying to understand the specific permissions I need to set on my Amazon S3 bucket. I've looked for this information already, but have only seen 1 or 2 examples of the new ACL/Policies that Amazon has implemented.
My use case: I'm using S3 to store images for my website (hosted elsewhere). I would like to upload images on S3 and be able to access them through their link on my own site.
I've used https://awspolicygen.s3.amazonaws.com/policygen.html to generate a GetObject policy:
{
"Id": "Policyxxxxxxxxxxxxxxxxx",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmtxxxxxxxxxxxxxxx",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::xxxxxx-xxxxx-xxxxxxx/*",
"Principal": "*"
}
]
}
These are my current Block public access settings:
Block all public access: Off
Block public access to buckets and objects granted through new access control lists (ACLs): On
Block public access to buckets and objects granted through any access control lists (ACLs): On
Block public access to buckets and objects granted through new public bucket policies: Off
Block public and cross-account access to buckets and objects through any public bucket policies: Off
In Access Control List, I have not added any permissions.
In Bucket Policy, I placed the policy I generated.
In CORS configuration, I specified localhost and my domain name as allowed origins and GET's as allowed methods.
Is this correct for my usage? It currently works, but I'm not 100% sure I've gotten the permissions right. All I need is public access to my photos (so my website can grab them) and to deny anything else (besides me logging in and uploading more photos).

Should I make my S3 bucket public for static site hosting?

I have an s3 bucket that is used to host a static site that is accessed through cloudfront.
I wish to use the s3 <RoutingRules> to redirect any 404 to the root of the request hostname. To do this I need to set the cloudfront origin to use the s3 "website endpoint".
However, it appears that to allow Cloudfront to access the s3 bucket via the "website endpoint" and not the "s3 REST API endpoint", I need to explicitly make the bucket public, namely, with a policy rule like:
{
"Sid": "AllowPublicGetObject",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::dev.ts3.online-test/*"
},
{
"Sid": "AllowPublicListBucket",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::dev.ts3.online-test"
}
That's all well and good. It works. However AWS gives me a nice big shiny warning saying:
This bucket has public access. You have provided public access to this bucket. We highly recommend that you never grant any kind of public access to your S3 bucket.
So I have two questions I suppose:
Surely this warning should be caveated, and is just laziness on AWS' part? Everything in the bucket is static files that can be freely requested. There is no protected or secret content in the bucket. I don't see why giving public read is a security hole at all...
For peace of mind, is there any way to specify a principalId in the bucket policy that will only grant this to cloudfront? (I know if I use the REST endpoint I can set it to the OAI, but I can't use the rest endpoint)
The first thing about the warning.
The list buckets view shows whether your bucket is publicly accessible. Amazon S3 labels the permissions for a bucket as follows:
Public –
Everyone has access to one or more of the following: List objects, Write objects, Read and write permissions.
Objects can be public –::
The bucket is not public, but anyone with the appropriate permissions can grant public access to objects.
Buckets and objects not public –:
- The bucket and objects do not have any public access.
Only authorized users of this account –:
Access is isolated to IAM users and roles in this account and AWS service principals because there is a policy that grants public access.
So the warning due to first one. Recomended policy by AWS for s3 static website is below.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::example-bucket/*"
]
}
]
}
Add a bucket policy to the website bucket that grants everyone access
to the objects in the bucket. When you configure a bucket as a
website, you must make the objects that you want to serve publicly
readable. To do so, you write a bucket policy that grants everyone
s3:GetObject permission. The following example bucket policy grants
everyone access to the objects in the example-bucket bucket.
BTW public access should be only GET, not anything else, Its totally fine to allow GET request for your static website on S3.
static-website-hosting