AWS Security Best Practice #10: Watch World-Readable and Listable S3 Bucket Policies

S3 has been around for quite some time. It may be the oldest Service in the ever expanding Web Services provided by Amazon. As a result, it has some legacy security controls which may lead to a level of confusion when trying to secure it.

S3’s maturity has also made it a target for people to troll for keys, passwords, and data they should not have access too. There have been several recent examples where an AWS key was compromised by publically accessible S3 content.

If you store intellectual property, source code, or other data that is important to your business in S3, it is important to understand how access to this is controlled.

By default, S3 does have a default Deny rule, so if you do nothing, only the account owner will ever be able to use S3. However, a quick review reveals three places where you can configure additional access to S3, IAM Policies, S3 Bucket Policies, and S3 Access Control Lists (ACLs).

Each one of these, or any combination of these, can be used to control access to S3, but as you grow with the service over time, it is possible to lose track of where or what is allowing access. This can open up security holes where you were not aware they existed. This can put your data at risk of loss or compromise.

The risk is compounded when you have multiple people who have managed your S3 service. Each individual may have had their own strategy for how best to secure access. When overlaid, these methods become hard to manage, difficult to visualize, and provide opportunity for missed security checks based on latest best practices.

As an example, S3 predates IAM. The security controls in place before IAM were, and still are, ACLs. Since they predate IAM, the ACL does not evaluate IAM users and you can inadvertently allow access where you thought the default deny rule kicked in.

AWS has a good article that helps explain this, titled “IAM Policies and Bucket Policies and ACLs! Oh, My! (Controlling Access to S3 Resources),” so we won’t go into the specific detail as so much to make sure you are aware.

More importantly, here is a graphic from that post that helps explain how these are evaluated together:

Given that you can control access to S3 in three different areas, we highly recommend that you choose one and use it consistently across your AWS account. This will go a long way to help you isolate security of your S3 environment. It helps to simplify where you will go and audit your S3 access as well.

So, as a security best practice, it would be highly recommended to not use any S3 ACL if you can. While these do offer an easy way to configure access, they should be considered a legacy security control and not used.

This leaves S3 bucket policies and IAM Policies. Which one of these you choose going forward should be based on a couple of things. First, which are you more experienced in managing based on your current workflow today?

If you are leveraging one more than the other, and it is working, it is okay to stick with that one. If you haven’t made a decision yet, I am going to reiterate what AWS include in the blog post above:

  • If you’re more interested in “What can this user do in AWS?” then IAM policies are probably the way to go. You can easily answer this by looking up an IAM user and then examining their IAM policies to see what rights they have
  • If you’re more interested in “Who can access this S3 bucket?” then S3 bucket policies will likely suit you better. You can easily answer this by looking up a bucket and examining the bucket policy

Pick one, and stick with it. Make it a policy going forward and try to stay away mixing them. It will be easier in the long run and for the people who follow in your footsteps.

It may also be a valuable use of time once you have chosen a method, to quickly audit your current policies and look for any place where you may have doubled up permissions.

Remember, S3 has a default deny rule, but there is also the ability that once you allow an action, unless you specifically deny someone (or everyone) you may have opened up S3 wider that you had intended.

While an extreme example, this may help. There is a bucket policy in the Hosting a Website on S3 that ensures an anonymous user (a web browser) can read any content in a bucket. If you put this policy on a bucket, it is the effect of a global allow rule to anyone not specifically denied access to an object.

If you were to put an IAM policy in place that denied access to that bucket, it would only prevent authenticated IAM users’ lists in your IAM policy. Everyone would still have the ability to GET objects in that bucket.

Granted, they could not list them because that permission is not there, but if they had the path, nothing would prevent them from getting the object since this rule allows it.

S3 is a mature service and does offers very good security. Take the time to make sure the resultant set of policies does what you expect it to do. Ideally, choose a single type of policy, either the IAM or S3 bucket policies to simplify where to audit this and keep it that way.

This will help ensure your data is kept under your control.

A quick recap of our past AWS Best Practice posts:

  1. Disable Root API Access Key and Secret Key
  2. Enable MFA Tokens Everywhere
  3. Reduce Number of IAM Users with Admin Rights
  4. Use Roles for EC2
  5. Least Privilege: Limit what IAM Entities Can Do with Strong Policies
  6. Rotate all the Keys Regularly
  7. Use IAM Roles with STS AssumeRole Where Possible
  8. Use AutoScaling to Dampen DDoS Effects
  9. Do Not Allow Unless You Mean It
  10. Watch World-Readable and Listable S3 Bucket Policies