Password protected directory and files in PHP

前端 未结 3 1000
盖世英雄少女心
盖世英雄少女心 2021-02-06 16:13

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

相关标签:
3条回答
  • 2021-02-06 16:35

    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.

    0 讨论(0)
  • 2021-02-06 16:40

    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.

    0 讨论(0)
  • 2021-02-06 16:46

    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.

    0 讨论(0)
提交回复
热议问题