Published in


Secure your public AWS S3 Buckets

Protect your app’s sensitive data with some simple measures

We often hear in the news that some apps have data breaches because of public AWS S3 buckets. I will show you how to avoid such an insecure setup.

What is the Problem with Public Buckets?

There are two problems:

  • (1) Everyone can list all files of your bucket
  • (2) Everyone can access every single file without authentication
List of all files of a public Bucket

So you can easily access the goku.jpgfile like so.

public files in S3 Bucket

Why have Public S3 Buckets?

The main reason could be having a lot of traffic on your app and wanting to move that traffic away from your app to a CDN. Therefore this can make sense if you are well aware of all security issues. Another reason can simply be missing knowledge on how to configure Buckets properly.

Solving (1) Everyone can list all files of your bucket

This is pretty easy to achieve. We simply let the “Block public access” setting on off — meaning the Bucket is still public accessible.

Block public access setting

But we remove the “List objects” for Everyone under Access Control List.

Access Control List without List Objects

When you open the root URL to your Bucket now, you should see Access Denied — which is exactly what we wanted.

List all files now denied

But now all uploaded files are also denied to be viewed publicly, therefore we need a Bucket Policy to allow GetObject.

Bucket Policy to allow GetObject

You can use the policy and only adapt the Resource to the ARN of your Bucket.

What did we achieve? We denied the listing of all files. But still every single file is publicly accessible.

Solving (2) Access to every single file without authentication

We can achieve this via two ways:

Solution (2a) Using “secret” URLs that cannot be guessed

  • Is less secure but in most cases sufficient if you still want the CDN benefit of not serving the files via your own infrastructure.

Solution (2b) Block public access to the Bucket

  • Is completely secure but means loosing the CDN benefit. You will serve the file via your own infrastructure after proper authentication and authorization.

We will have a look at both solutions.

Solution (2a) Using “secret” URLs that cannot be guessed

To explain this approach let me first explain a bad solution where listing all files is disabled but the URLs to each file can be guessed.

  • https://app3000-data.s3…
  • https://app3000-data.s3…
  • https://app3000-data.s3…

We can write a simple for-loop and download all user avatar.png files by easily incrementing the userId.

The “secret” URL approach would be to use a hashing algorithm such as SHA512 to hash the userIds. The URLs would then look like this (shortened the hashes for readability)

  • https://app3000-data.s3…
  • https://app3000-data.s3…
  • https://app3000-data.s3…

As you can see the userIds are hashed now and for a strong hash it cannot be guessed. You can make this even more secure if you hash the filename as well.

But be aware if your app is providing sensitive data this is not fully secure. Maybe have a look a the (2b) solution. But this approach still gives you the CDN benefit and for insensitive data this approach could be fine.

Solution (2b) Block public access to the Bucket

The more secure solution is to not publicly expose the AWS S3 Urls to the end-user. Instead use AWS S3 as storage but completely hiding it from the user. You will loose the CDN benefits, but gain full control over authentication and authorization.

Therefore first change your bucket or create a new bucket with enabled “Block all public access” setting.

Block all public access

Now no one can access the file list and files via the S3 URLs anymore.

The big picture of our app security is now like so.

But that means we need to provide an Endpoint to do so instead. We do this in NodeJS with Express and can then use this URL to get our files from S3

You can rest assured your files are safe. Lastly you could enable on-the-fly encryption of your files and then there should be no issues regarding security anymore :)

Enable Object Encryption

Passion, friendship, honesty, curiosity. If this appeals to you, Comsysto may well be your future. Apply now to join our team!




Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Bernhard @ Comsysto Reply

Bernhard @ Comsysto Reply

Lean Java Expert working for Comsysto Reply GmbH