Securing Your Downloads
Whether on a commercial project, a community project or a small personal project you will inevitably at some point need to restrict access to download files with a password, a login or some other authentication.
Here I will describe a very simple method to restrict access to the files using Apache(web server) and then grant access with PHP.
Sometimes as a hack solution developers will place files in random directories with random names and then have a PHP page invisibly redirect to the file. However, as you may have guessed if someone is determined enough this isn't really a solution and security through obscurity isn't much of a solution.
The solution
The answer is to use a .htaccess file and a PHP download file. (.htaccess files are special files which give Apache special instructions on how to serve files etc.)
Create a directory called "files". This will contain our files and our .htaccess
Put this in a .htaccess file in the directory:
Order Deny,Allow
Deny from all
This will simply disallow all access to the "files" directory.
Next create a PHP called download.php, but place it in a folder outside files!
<?php function send_download($filename, $display) { if ( connection_status()!=0 ) { return( False ); } //Make sure people don't 'inject' and try and change folders $filename = preg_replace( '@(\.\.|/)@', '', $filename ); //File_exists will return true at a certain length, and may throw errors $filename = substr($filename,0,100); //binary/octet-stream header("Content-type: binary/octet-stream"); header('Content-Disposition:attachment;filename="'.$display.'"'); header("Pragma: public"); header("Cache-control: private"); header("Content-transfer-encoding: binary\n"); header("Expires: 0"); header("Pragma: no-cache"); header("Content-length: ".filesize($filename).""); readfile( $filename ); $status = (connection_status()==0); return($status); } //Check if they are allowed to download the file!! $can_dl = true; //You can put any user-check code in here if( $can_dl == true ) { $file = isset($_GET['f'])?($_GET['f']):(''); if( $file!='' ) { $file = 'files/'.$file; //Send the download to them! send_download( $file ,$file ); } }
Now, by accessing the page download.php?f=demo.exe for example it would send you the file "files/demo.exe" if the user is allowed.
For you the important part is the "if" statement:
//You can put any user-check code in here if( $can_dl == true ) {Replace the statement in here with a database user lookup, a password check or even an IP check to verify the user has permission to download the file they want.


