Bucket Policy for your Public S3 Bucket

Recently I came across multiple AWS S3 buckets with directory listing enabled. The content in the buckets ranged from simple images & js files to images of aadhaar ID, PAN cards, etc.

Security is a non-functional requirement of business. What I have seen so far is that if a developer gets an idea, he/she will work to implement the idea without thinking much about the security of the product. But in the long term when the product matures, even small misconfigurations could lead to huge security vulnerabilities.

Amazon does a very good job in showing if a bucket is public or not. When a bucket is made public, you can see a tag under “Permissions” which says that the bucket is public.

If you ever come across a developer / maintainer who says that he / she didn’t know that the bucket was public, just DONT TRUST because Amazon tells them its public everytime they see the Management Console.

Notification 1

But its not just the fault of user. If an inexperienced person wants to create S3 bucket with content that should be readable by all users, he/she would goto “Permissions”, check for something similar to Read Access (Public access with List Objects) and will enable it.

Notification 2

What happens when the user performs this action is that the files are readable by everyone, at the same time files in every directory is also publicly listed when you visit http://bucketname.s3.amazonaws.com.

One can use S3 bucket policy to enable only the required actions (like GetObjects, PutObjects, etc). I am giving out the S3 bucket policy which I personally use. What this policy does is, it allows unauthenticated public access to the objects in the bucket but disables directory listing. Putting in simple terms, a user could access a file in S3 if he/she knows the exact location of the file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1405592139000",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::bucketname/*",
                "arn:aws:s3:::bucketname"
            ]
        }
    ]
}

Note: Replace bucketname with the name of your S3 Bucket.

If you have a better solution than this, please let me know in the comments.