Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Password protected directory and files in PHP

Tags:

security

php

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 can download the file without the authentication. So what I can do to avoid this? I can make a HTTP Authentication but I want a custom login form and not the window popping out.

Any idea?

Thanks

like image 435
Alex Avatar asked Dec 22 '22 01:12

Alex


2 Answers

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.

.htaccess in ./downloads/ :

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 ./

index.php in ./ :

<?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.

like image 180
Pierre Espenan Avatar answered Jan 07 '23 02:01

Pierre Espenan


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.

like image 28
Yes Barry Avatar answered Jan 07 '23 00:01

Yes Barry