Anfaenger Posted March 25, 2009 Share Posted March 25, 2009 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! Quote Link to comment https://forums.phpfreaks.com/topic/151104-solved-force-download/ Share on other sites More sharing options...
conormacaoidh Posted March 25, 2009 Share Posted March 25, 2009 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. Quote Link to comment https://forums.phpfreaks.com/topic/151104-solved-force-download/#findComment-793794 Share on other sites More sharing options...
MadTechie Posted March 25, 2009 Share Posted March 25, 2009 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"); Quote Link to comment https://forums.phpfreaks.com/topic/151104-solved-force-download/#findComment-793797 Share on other sites More sharing options...
Anfaenger Posted March 25, 2009 Author Share Posted March 25, 2009 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 Quote Link to comment https://forums.phpfreaks.com/topic/151104-solved-force-download/#findComment-793809 Share on other sites More sharing options...
Anfaenger Posted March 25, 2009 Author Share Posted March 25, 2009 conormacaoidh: I figured it out ... the mistake was to use: /download..... which does not return anything; if download/... is used it is correct. Stupid mistake.... Thank you. Quote Link to comment https://forums.phpfreaks.com/topic/151104-solved-force-download/#findComment-793835 Share on other sites More sharing options...
MadTechie Posted March 25, 2009 Share Posted March 25, 2009 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"); } ?> Quote Link to comment https://forums.phpfreaks.com/topic/151104-solved-force-download/#findComment-793960 Share on other sites More sharing options...
Anfaenger Posted March 25, 2009 Author Share Posted March 25, 2009 Thanks MadTechie you've been a great help. Most people recommend to avoid this script but with you additions I guess it is safe to use. Thanks Quote Link to comment https://forums.phpfreaks.com/topic/151104-solved-force-download/#findComment-794025 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.