0

I'm currently using this PHP download script to a serve long list of large files (1GB+) from my website, but after complaints of corrupt downloads I researched and found a better looking alternative: mod_xsendfile. My hosting is with Dreamhost, and they've already enabled xsendfile on my domain. I tested it using this code from the authors website, and it works:

<?php 
header("X-Sendfile: /home/username/website.com/test.zip");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=test.zip");
exit;
?>

But I would like to have all of the downloads in one directory and link to the files like I do with the script from media division:

https://website.com/download.php?file=test.zip

I've searched through most of the questions tagged with x-sendfile and didn't find anything helpful. I can't write PHP code, but know enough to configure scripts to get them working. Does anyone know of a script that can do this or can help me out?

Thanks

1 Answers1

0

That could be done like this:

<?php 
$path = realpath("/home/username/website.com/" . $_GET["file"]);
if (strpos($path, "/home/username/website.com/") !== 0) {
    header("Status: 404 Not Found");
    die();
}
header("X-Sendfile: $path");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=".$_GET["file"]);

This also makes sure the user can't get a file from any other directory then /home/username/website.com/, e.g. a database backup or something else you don't want to get downloaded.

Johann Bauer
  • 2,488
  • 2
  • 26
  • 41
  • Works great, thanks! Instead of using the full path I changed it to this: `$path_to_file = 'files/'; header("X-Sendfile: $path_to_file".$_GET["file"]);` Which seems to work ok, as I have all of the downloads I want to link to in the "files" directory. Also, is there a way to be able to link to subdirectories within the files directory? something like: `https://website.com/download.php?file=subdir/test.zip` – Twisted.Raven Jan 26 '15 at 04:32
  • I know this is an old thread but, for future generations: MAKE SURE ```$_GET['file']``` is properly escaped. If not user can request ANY file from the filesystem. For example by requesting ```../../../../etc/passwd```. – Mike Doe May 14 '15 at 09:01
  • @mike That's why i checked if there is a / in the file name. Attacks like that would not be possible using this script. – Johann Bauer May 14 '15 at 12:40
  • Attack is still possible on Windows-like systems. – Mike Doe Jun 24 '15 at 11:18
  • And on the Unix-style systems as well with such `file` query: `%2e%2e%2fetc%2fpasswd` which becomes `../etc/passwd`. You should not advice anyone about security if you don't know what your code really does. – Mike Doe Jun 24 '15 at 11:25
  • @mike what would be a correct way to fix this then? – Twisted.Raven Aug 03 '15 at 20:23