PHP display/download directory files outside the webserver root

前端 未结 3 1476
礼貌的吻别
礼貌的吻别 2021-01-23 19:38

I have downloaded and added this very simple, one file, php web file explorer system(called Indexer) to my XAMPP server.

My XAMMP server is on my C: drive, but I want In

相关标签:
3条回答
  • 2021-01-23 19:59

    Your web server can not see the files outside the DocRoot, so it can not serve the files via the browser with direct links. You need to print their contents into the browser with readfile() with the headers properly set.

    To make this work, you need to change the configuration in indexer.php:

    // this way it works with accentuated letters in Windows
    $Root = utf8_decode("G:\test"); // define the directory the index should be created for (can also be located outside the webserver root)
    
    $AllowDownload = TRUE; // enclose file items with the anchor-tag (only makes sense when the files are in the webserver root)
    // you need to place download.php in the same directory as indexer.php
    $WebServerPath = dirname($_SERVER['SCRIPT_NAME']) . "/download.php?path="; // path where the indexed files can be accessed via a http URL (only required when $AllowDownload is TRUE)
    

    And you have to place a new file called download.php in the same directory as indexer.php, with this content:

    <?php
    
    // it must be the same as in indexer.php
    $Root = utf8_decode("G:\test");
    
    function checkFileIsInsideRootDirectory($path, $root_directory) {
        $realpath = realpath($path);
    
        if (!file_exists($realpath))
            die("File is not readable: " . $path);
    
        // detects insecure path with for example /../ in it
        if (strpos($realpath, $root_directory) === false || strpos($realpath, $root_directory) > 0)
            die("Download from outside of the specified root directory is not allowed!");
    }
    
    function forceDownload($path) {
        $realpath = realpath($path);
    
        if (!is_readable($realpath))
            die("File is not readable: " . $path);
    
        $savename = (basename($path));
    
        header("Pragmaes: 0");
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Cache-Control: private", false);
        header("Content-type: application/force-download");
        header("Content-Transfer-Encoding: Binary");
        header("Content-length: " . filesize($path));
        header("Content-disposition: attachment; filename=\"$savename\"");
    
        readfile("$path");
        exit;
    }
    
    if (!isset($_GET['path']))
        die("Path not specified!");
    
    $fullPath = $Root . $_GET['path'];
    
    checkFileIsInsideRootDirectory($fullPath, $Root);
    
    forceDownload($fullPath);
    
    0 讨论(0)
  • 2021-01-23 19:59

    You have to change your apache configuration. The problem is not the php script, the problem is the webserver (which is not able to serve files outside web root, unless you configure it to).

    Try something like this in your apache configuration:

    Alias /testalias "G:/test"
    <Directory "G:/test">
      Options Indexes FollowSymLinks MultiViews ExecCGI
      AllowOverride All
      Order allow,deny
      Allow from all
    </Directory>
    

    This tells Apache to serve files from G:/test when you access http://localhost/testalias

    Then change your script configuration like that:

    $WebServerPath = dirname("testalias");
    

    and it should work!

    0 讨论(0)
  • 2021-01-23 20:14

    Let's take a look at that script:

    $Root = realpath("."); // define the directory the index should be created for (can also be located outside the webserver root)
    $AllowDownload = TRUE; // enclose file items with the anchor-tag (only makes sense when the files are in the webserver root)
    $WebServerPath = dirname(getenv("SCRIPT_NAME")); // path where the indexed files can be accessed via a http URL (only required when $AllowDownload is TRUE)
    

    Notice "only makes sense when the files are in the webserver root" and "path where the indexed files can be accessed via a http URL". Which indicates that this script was not designed to be able to download files that are outside the web server root dir.

    However, you could modify this script to be able to do that in the way that styu has noted in his answer. You could then send your changes to the author of the script.

    BTW, I tested this on my own server.

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