1

I am wondering how to make a download server more robust. For now, I have a server, on https, storing zip files, named with a random hash, indexed by my database. The directory containing does not permit listing (htaccess) to avoid manual download directly browsing the directory on the server.

The Java app displays the description of the files, and if the user wants to download it, he simply clicks on download. Java app, if that user is allowed to download, sends to credentials to my PHP script on the server, the PHP script checks them, checks again if that very user is allowed to download that file, retrieves the filename.zip from DB indexed by the file ID the user wants to download, and echoes back that file name. The Java app reads that filename and downloads the file using

Url url = new URL("https://myserver.com/assets/theAssetToDownload.zip")
URLConnection urlConn = url.openConnection();

InputStream is = urlConn.getInputStream();
FileOutputStream fos = new FileOutputStream("test.zip");

byte[] buffer = new byte[4096];
int len;

while ((len = is.read(buffer)) > 0) {
    fos.write(buffer, 0, len);
}

(shortened the code, needs try/catch, is/fos.close() etc etc)

So far so good, it works well... But... If someone enters, in a browser, the direct url, the file will also be downloaded, without clear check on the authorisation...

So I thought, hey, do not let anybody but the PHP script to access the assets directories! Again, that's a simple htaccess.

But how is the download served then?

Would that be a header and output in my PHP script, like:

header("Content-type: application/octet-stream");
header("Content-disposition: attachment;filename=test.zip");
readfile(test.zip);

In that case, how do I read that from Java side? Also with a getInputStream()?

I do understand that question is generic. How can I do it securely?

halfer
  • 19,824
  • 17
  • 99
  • 186
Psychokiller1888
  • 620
  • 2
  • 10
  • 25
  • 1
    The issue here simply is that you offer a direct http download of those files. You should not. Instead of returning the file name, so indirectly the url to download a file you should return the _content_ of the file. That's it. – arkascha Dec 06 '15 at 11:30
  • Yeah, I know the issue, that's why I decided to ask from people certainly knowing how to do, before rewriting everything I wanted to be sure the header/readfile method should be the one used. Thank you for your answer! – Psychokiller1888 Dec 06 '15 at 14:48
  • Hi @Psychokiller1888. Just a quick note - we encourage post authors here to accept good edits to their material. See the help article [Why can people edit my posts?](https://stackoverflow.com/help/editing) If an author's _meaning_ is changed, then it is OK to edit again, but that is not the case here. – halfer Jun 08 '20 at 07:09

1 Answers1

1

You could store the file somewhere not accessible from the web, but still readable to the web server, and then with htaccess route all requests to your php script. Combine that with what you already have (headers, output with readfile), and authorization, and that should be it.

Schlaus
  • 18,144
  • 10
  • 36
  • 64