-1

I have been looking to find a good guide on how to securely download files from a website only if a user session exists.

The files in the download folder should NOT be accessible if a user session doesn't exist.

Therefore I assume the folder the files are stored in needs to be "locked" by a .htaccess file? Alternatively stored outside the root folder? Which is the best?

If anyone could point me to a good guide/tutorial for this it would be very much appreciated. Thanks

Marcus Silverman
  • 243
  • 1
  • 7
  • 22
  • 2
    See [this in general](https://stackoverflow.com/a/5813380/231316) and maybe [this for `fpassthru`](https://stackoverflow.com/a/26784775/231316) – Chris Haas Mar 25 '21 at 17:35
  • Thanks, but is there a preferred method, or doesn't it make any difference? Which is better, store files outside the root folder, or a folder locked by .htaccess? – Marcus Silverman Mar 25 '21 at 21:28
  • https://stackoverflow.com/help/on-topic: _“Questions asking us to recommend or find a book, tool, software library, tutorial or other off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam.”_ – CBroe Mar 26 '21 at 07:24
  • 1
    The benefit of storing outside of your app is that your server config doesn’t have to be aware of your app. I also host on Nginx where htaccess is not an option, so it helps there, too. Make sure you test that you can’t get hit by directory traversal exploits – Chris Haas Mar 26 '21 at 12:02

1 Answers1

0

This is what I ended up doing which worked well. In my scenario I store my files outside of the root folder.

$filename= $_GET['filename'];

// the file path and file you want to send inline
$path = $fileroot."/files/".$filename;

if(!file_exists($path)) {
  die("There has been an error unfortunately");
}

// the file name of the download, change this if needed
$public_name = basename($path);

// get the file's mime type to send the correct content type header
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime_type = finfo_file($finfo, $path);

// header("Content-Disposition: attachment; filename=$public_name;");
//Use "attachment" instead of inline if you want direct download instead

// send the headers
header("Content-Disposition: inline; filename=$public_name;");
header("Content-Type: $mime_type");
header('Content-Length: ' . filesize($path));

readfile($path);


Marcus Silverman
  • 243
  • 1
  • 7
  • 22