Jump to content

Recommended Posts

I found the following code to force downloads:

 

<?php

$filename = $_GET['file'];

// required for IE, otherwise Content-disposition is ignored
if(ini_get('zlib.output_compression'))
  ini_set('zlib.output_compression', 'Off');

// addition by Jorg Weske
$file_extension = strtolower(substr(strrchr($filename,"."),1));

if( $filename == "" ) 
{
  echo "<html><title>eLouai's Download Script</title><body>ERROR: download file NOT SPECIFIED. USE force-download.php?file=filepath</body></html>";
  exit;
} elseif ( ! file_exists( $filename ) ) 
{
  echo "<html><title>eLouai's Download Script</title><body>ERROR: File not found. USE force-download.php?file=filepath</body></html>";
  exit;
};
switch( $file_extension )
{
  case "pdf": $ctype="application/pdf"; break;
  case "exe": $ctype="application/octet-stream"; break;
  case "zip": $ctype="application/zip"; break;
  case "doc": $ctype="application/msword"; break;
  case "xls": $ctype="application/vnd.ms-excel"; break;
  case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
  case "gif": $ctype="image/gif"; break;
  case "png": $ctype="image/png"; break;
  case "jpeg":
  case "jpg": $ctype="image/jpg"; break;
  default: $ctype="application/force-download";
}
header("Pragma: public"); // required
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false); // required for certain browsers 
header("Content-Type: $ctype");
// change, added quotes to allow spaces in filenames, by Rajkumar Singh
header("Content-Disposition: attachment; filename=\"".basename($filename)."\";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filename));
readfile("$filename");
exit();

?>

The author states that there is security issue:

http://www.yoursite.com/force-download.php?file=filepath

 

It is VERY STRONGLY recommended that the above functionality is only used internally and is not viewable from the web site since this would represent a security breach of the site.

 

 

Security

 

If you expose this in a URL you are essentially posting a large sign titled "Hack me!"

 

What to do? Use literal values to represent your files that you would access, thus a value of "1" would represent the file xyz.pdf, a value of "2" would represent the file abc.mp3, and so on. Thus the only DOWNLOADABLE files are those specifically HARD-CODED in your script.

 

I don't understand how this can be used internally without posting the http://www.yoursite.com/force-download.php?file=filepath somewhere?

 

Would it be possible to just call the script  via  http://www.yoursite.com/force-download.php

and force a download i.e. http://www.yoursite.com/download/test.doc without providing the path?

 

Can this script be limited to a a special folder i.e. download so that there only files from that folder can be downloaded or would there still be a security problem?

 

Thank you for you input!

Link to comment
https://forums.phpfreaks.com/topic/151104-solved-force-download/
Share on other sites

What I usually do is add something in the url like ?download=1 and then have a predefined list of files. This would then download the file associated with the number 1. This stops hacking because people can only download files that are on the list. There is one problem with this method; it is not dynamic... I suppose you could fetch a list of available files for download from mysql to make it dynamic.

I agree with what conormacaoidh said,

 

as thats quite secure, however it also boils down to what you don't want them to download

for example if you ONLY wanted them to download files of the types you have listed to could change

 

default: $ctype="application/force-download";

to

default: die("Error: downloading");

Thank you for the replies.

 

conormacaoidh: How would you define those values in the script?

I tried something like:

$1='/download/test.doc'

but this does not work....

 

MadTechie: If I would for example only add

case "doc": $ctype="application/msword"; break;

and

 

default: die("Error: downloading");

 

a user could only download .doc files? That would be pretty safe.

 

Thank you

MadTechie: If I would for example only add

case "doc": $ctype="application/msword"; break;
default: die("Error: downloading");

 

a user could only download .doc files? That would be pretty safe.

 

thats correct..

 

as for locking it to only selected file, you could do this

 

<?php
$allow = array("myfile.doc", "anotherfile.pdf", "youget.the", "idea.pdf");
$filename = $_GET['file'];
if(!in_array($filename,$allow)) //or an SQL query!
{
die("Invalid FILE");
}
?>

 

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.