Storing and serving files securely for multiple clients

Tamás Pap asked:

We are working on a web app, where (among other features) our users can upload their files.
However we can’t store these files on our VPS because storage space is limited, so we decided to go with S3.

The main problem is that we must make sure users can access only their own data.
So we keep the list of files in our database, and the list of users having access to them.
Our server can easily decide if a user has, or not, access to a file. But how to actually serve the files to users?

There are some possibilities I’ve already considered, however none of them actually seems to be the best one.

1. Generating (expiring) signed urls with PHP

This is a really simple approach, it is also fast but results in very very ugly and long urls.

Here’s how to do it.

2. Obfuscated URLs

This means, that we keep the files public for read on S3, but all the files are stored in hard to guess named folders like: 24fa0b8ef0ebb6e99c64be8092d3ede20000. However, maybe this is not the safest way to go. Even if you can never guess a folder name, after you know it (because you actually have access to it), you can share that link with anybody (with any not authorized person).

3. Download the files through our server

This means that the files are not served directly by S3, but first our server reads it securely and serves it. We really don’t want this 🙂

4. Checking referrer

The Obfuscated URLs solution can be improved by “making sure” the request comes from our server (you can set up S3 to check the referrer). However this would be a very unreliable solution, because not all browsers send the referrer data, and it can also be faked.

What is a good way to serve files from Amazon S3 securely for different clients?

My answer:


Use Amazon S3 pre-signed queries to serve the S3 objects directly to users after doing whatever user validation you wish. This method creates a time-limited URL to which you can redirect users.


View the full question and answer on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.