EDIT: I received an email from Filepicker CEO, Brett van Zuiden
As fanastic as this service is, however, that last bit struck me as odd.
Here is an example call to getFile():
Now, the API key is obviously needed. It also makes sense to have the services mapping here, as it doesn’t really concern the backend. However, from a security standpoint I couldn’t see why on earth the maximum upload size and MIME type limiter would be specified client side.
After some analysis it seems that getFile() makes a AJAX call that:
- Requests https://filepicker.io/api/upload/
- Passes a URL-encoded GET parameter named “js_session”
- Sends the file as POST paramater named “fileUpload”
The request includes the MIME type (the server checks the MIME of the file), API key, and some other options. The server then responds with this JSON object:
The entire process is relatively simple. So, I wondered, what happens if I preform the same request with my own script?
Successfully, using a script that makes the same requests, I upload a placeholder image and then download it to verify it worked.
Since we send the MIME type limiter in the request, by removing it we can theoretically upload any file type we like.
Let’s give it a shot?
We take advantage of some linux devices to generate a 2MB file of random data, then upload it. After doing that, we download it and verify that it is identicle. And it worked perfectly.
So we can upload 2MB files of any file type. What exactly are the size limits then?
200MB? Still appears no.
I stopped testing after uploading a 419MB file of random binary data, then downloading and comparing that the upload was successful. It’s important to remember that with someone’s API key, all of this data is shoved directly into their Amazon S3 bucket and downloaded on their dollar.
The folks are Filepicker.io are very clearly aware that someone might use a script to upload files instead of their library. In fact, the CEO and Founder actually mentioned that this particular script was a “cool little tool” (which it is). This makes me wonder if I am actually missing some particularly powerful security features they have, or if they just didn’t think of ways in which this might be severely abused. So I checked the “Developer Home” interface that they provide.
As you can see, it does appear that they provide a security measure. The App URL, as they describe, sounds like it checks the referer of the client. If they don’t appear to be making the request from your app’s URL, they deny the upload. The only problem is that HTTP referers are sent just as plain headers, meaning they can be easily spoofed. It is trivial to fake your referer, and to test this I added it directly into my Python upload script.
The possible abuses for this are endless. Pirates and Hackers could be storing their files in your S3 bucket, and others downloading them on your dollar. Unfortunately, in addition the owner of the bucket might quite possibly be held accountable for legal implications and copyright damages. Hopefully the Filepicker team will be quick to either get this fixed, or point out where I made my mistake ;)
The finish script is on Github.
Updated October 11, 2012: Added email from Filepicker’s CEO
Updated April 5, 2015: Added syntax highlighting