1

Users have the possibility to upload a sensitive personal file to a specific website. After uploading, only the user himself and the administrator of the website have the ability to download the file again.

All files of any user are uploaded to the following folder: https://example.com/folder/uploads/.

Before a file is uploaded, it gets renamed to <<username>>.docx.

So for Foo the path would be: https://example.com/folder/uploads/foo.docx and for Gux it'd be https://example.com/folder/uploads/gux.docx.

As you can see, this is not safe at all. Foo could simply examine the download link, and replace his own name in the file-path with the username of other users to download their files.

So to prevent this, the web-developer did the following: Before a file is uploaded, a random string of 15 characters gets prepended to the filename. This random string is different for each upload.

For Foo this would be for example https://example.com/folder/uploads/heh38dhehe83ud37_foo.docx and for Gux https://example.com/folder/uploads/abcnjoei488383b22_gux.docx.

When Foo examines the download-url, he will know in which folder all the files are stored. But there is no way that he could guess the random string that is prepended to Gux' file. The random string actually functions as a 15-character long password.

In all directories an index.html-file is placed so the directory content does not get listed.

If Foo still wanted to download other users their files, how would he do that? I'm looking for a way Foo would do this by forming a specific URL or HTTP-request. Breaching the server or database is a correct answer but not the kind I'm looking for.

TL;DR: How to find the path of a file on a public website with a unique and randomized string in it? You know the path to the upload-folder, but there is a index.html-file there so you can't see the content.

  • When you ask "How", are you questioning whether someone can guess another's file? Or "How" as in how was this setup to work? The string could easily be a hash of some type and checked against the user's hash, and it is fairly basic authentication at that point. – Nelson Jul 8 at 2:34
  • @Nelson Yes, I am asking if a random person could guess another's file. And how would that work. The string is no hash. It truly is a list of random characters not based on any info of the user. – O'Niel Jul 8 at 2:46
  • If it is truly random, then you brute force it. There isn't really a whole lot can be done to stop it. I can make hundreds of URL requests a second and it'll spin through all possibilities within the hour. It's not remotely secure if someone spends any effort trying to steal your files. – Nelson Jul 8 at 2:52
  • Seems there's something missing at the authorization layer to allow this. As @Nelson mentioned, this is trivial brute force. – user2320464 Jul 8 at 6:06
  • 3
    @user2320464: " The glaring issue remains the failure in the authorization layer." - The approach of unguessable URL's is a fairly common one and often used to have a way to share files without with others - without the need to setup user accounts, password etc just to share a single file. Properly implemented this approach is safe for the use case it is intended for. – Steffen Ullrich Jul 8 at 10:28
1

Under the following assumptions, the approach is safe:

  • the 15-byte prefix is truly random
  • the character set of the prefix consists of numbers and the characters a to z. (given the file name examples that O'Niel provided).

In practical terms, the file name cannot be guessed or bruteforced because the search space is too huge (as @schroeder correctly comments).

Let's do the math:

Calculating the search space: 36 ^ 15 = 2.2107391972073336e+23

If any kind of supercomputer setup was to bruteforce this in say, a 100 years (approx. 3.1536e+9 seconds), then it had to try more than 7e+13 possibilities (70 trillion (short scale)) per second.

Which, of course, does not seem feasible.

| improve this answer | |
  • @O'niel: You asked that user needs to able to download the file after uploading it. How will user "foo" know know the file name "heh38dhehe83ud37_foo.docx" e.g. 1 month after uploading it? How this answers your question? – mentallurg Jul 9 at 9:09
0

Since you know user name:

  1. Using of random symbols during upload is not necessary. Just check that file name matches user name.
  2. Same for download: On the server side check that user name and file name match.
  3. User name is determined during login. One user cannot use name of other user, and thus cannot access files of any other user.

In case you need more than one file per user, use separate directory per user.

| improve this answer | |
  • 3
    Doesn't this work only if you have a web app with a single entry point, so the entry point can check permissions and then route the request to the right resource? Otherwise, a direct request the URL of the file will just download it. BTW, in a typical CMS (Wordpress, Joomla, etc.) only the request to non-existent files will be redirected to the single entry point index.php, but if you request an existing file (like /uploads/example.txt), it will be downloaded directly. – reed Jul 8 at 9:02
  • @reed: No, no single entry point is not needed. In Java you can do it e.g. as a servlet filter, in .NET via similar mechanism, in PHP e.g. by using page template with the common part that would check the current user. – mentallurg Jul 9 at 9:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.