Amazon S3 has emerged as a dominate player in providing a white box cloud storage solution for numerous organization. However, while S3 is great for outsourcing public web content, private, user-specific content is not something it handles quite as well. When storing private files, 3 solutions come into play:
- Transfer the files back and forth between your servers and S3. This is cumbersome, as you incur a bandwidth toll on both your server and S3 and a performance penalty (the extra time to transfer to/from S3). However, it can be a valid solution based upon the specifics of your storage needs.
- Add users to the access control list of S3 objects. This is usually not a feasible solution as it requires users to have an AWS account and authenticate with AWS.
- User query string authentication on objects. This will allow public access to an object for a certain period of time. While this will allow access, this is also where the security gap is, as during the interval of time when the file is public, anyone can access it given the URL.
The security gap came into play as I was experimenting with the drop.io API and a drop with the guest password set. Once you pull the list of assets in a drop, you get a link with each asset to access the file (well, typically, a converted version of the file, as you can’t get original files back unless your a premium user – in any case, the data is visible). This URL redirects to a query string authenticated S3 object which can be accessed publicly.
The problem here is that there is no encryption between drop.io and the client (it’s all plain old HTTP), so it’s not unreasonable to assume that a hacker using a packet sniffer could pick up the URL. Said hacker would then simply have to put the URL into a browser to download the asset. To verify this, I traced the HTTP request and response with Wireshark and, as I expected, was able to easily get the asset URL,