Im creating a simple private page with links to some files to download. I\'ve done it with simple session management but I have a problem: if somebody click on the file-url he c
The top answer is definitely the way to protect other people from viewing the directory directly, but there's a better way to fix the PHP download vulnerability:
if (isset($_GET['filename']) && basename($_GET['filename']) == $_GET['filename']) {
// the author's code
$my_download_folder = "./downloads/";
header("Content-type: application/force-download");
filename=".basename($my_download_folder . $_GET["filename"]));
readfile($my_download_folder . $_GET["filename"]);
} else {
// shoot back an error if the file that user wants to download is not permitted
}
So just wrap around his PHP code with this if/else statement to prevent others from exploring your server.
I guess it's a little bit late to answer. Anyway, it may help other people.
To protect files from direct downloads, you have to use a combinaison of PHP + .htaccess.
Let's admit that ./downloads/ is the folder where you store files you want to be downloaded. First, you have put .htaccess in this folder.
deny from all
This will protect the folder to everybody, except scripts wich are executed on the server side.
Here is an example of a PHP script you can write at the root directory ./
<?php
if(!empty($_GET["filename"]))
{
//Here is the path to the folder containing files to download
$my_download_folder = "./downloads/";
//Preparing headers
header("Content-type: application/force-download");
//You can use more headers :
//header("Content-Length: ".filesize($my_download_folder . $_GET["filename"]));
//header("Content-Disposition: attachment; filename=".basename($my_download_folder . $_GET["filename"]));
//You can check if the file does exist
//if (!file_exists($my_download_folder . $_GET["filename"]))
//exit();
//Reading file will trigger download on the browser side
readfile($my_download_folder . $_GET["filename"]);
}
?>
<html>
<form action="" method="GET">
<input type="text" name="filename" id="filename" />
<input type="submit" value="Download It !" />
</form>
</html>
This script is usable as it is. But be careful. Actually there is a major vulnerability : With this form you can download any file of the server (including a file like config.php which contains access to your database). To fix that vulnerability you can use IDs :
if ($_GET["id"] == 1)
$filename = "toto.pdf"
if ($_GET["id"] == 2)
$filename = "fish.png"
It provides a good example of protecting files from direct download but not from PHP download.
Here is a very simple solution using htpasswd (quick and easy and it works).
$ cd /path/to/password_protected_dir
$ vi .htaccess
Then within your .htaccess file you will need to add this:
AuthUserFile /path/to/.htpasswd
AuthGroupFile /dev/null
AuthName "My Private Directory"
AuthType Basic
<Limit GET POST>
require valid-user
</Limit>
Next you will generate the .htpasswd file which you just included in the .htaccess file as show above. You can do this like so:
$ htpasswd -c .htpasswd user_name
At this point you will be prompted to enter the password.
Of course, this is merely one method of accomplishing this.