受密码保护的PHP目录和文件

时间:2010-07-02 14:54:32

标签: php security

我正在创建一个简单的私人页面,其中包含要下载的某些文件的链接。我已经完成了简单的会话管理,但我遇到了一个问题:如果有人点击文件网址,他可以在没有身份验证的情况下下载文件。那么我可以做些什么来避免这种情况呢?我可以进行HTTP身份验证,但我想要一个自定义登录表单而不是窗口弹出。

有什么想法吗?

由于

3 个答案:

答案 0 :(得分:8)

我想回答有点晚了。无论如何,它可以帮助其他人。

要保护文件不被直接下载,您必须使用PHP + .htaccess的组合。

我们承认./downloads/是您要存储要下载的文件的文件夹。 首先,你已将.htaccess放在此文件夹中。

./downloads/中的

.htaccess:

deny from all

这将保护文件夹给所有人,除了在服务器端执行的脚本。


以下是您可以在根目录下编写的PHP脚本示例./

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>

此脚本可以原样使用。不过要小心。实际上有一个主要的漏洞: 使用此表单,您可以下载服务器的任何文件(包括config.php等包含数据库访问权限的文件)。 要修复该漏洞,您可以使用ID:

if ($_GET["id"] == 1)
    $filename = "toto.pdf"
if ($_GET["id"] == 2)
    $filename = "fish.png"



它提供了一个很好的例子来保护文件免受直接下载,但不能从PHP下载。

答案 1 :(得分:2)

最佳答案绝对是保护其他人不直接查看目录的方法,但有更好的方法来修复PHP下载漏洞:

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
}

所以只需用这个if / else语句包装他的PHP代码,以防止其他人探索你的服务器。

答案 2 :(得分:1)

这是使用htpasswd的一个非常简单的解决方案(快速简单且有效)。

$ cd /path/to/password_protected_dir
$ vi .htaccess

然后在.htaccess文件中,你需要添加:

AuthUserFile /path/to/.htpasswd
AuthGroupFile /dev/null
AuthName "My Private Directory"
AuthType Basic

<Limit GET POST>
require valid-user
</Limit>

接下来,您将生成.htpasswd文件,该文件刚刚包含在.htaccess文件中,如上所示。你可以这样做:

$ htpasswd -c .htpasswd user_name

此时系统会提示您输入密码。

当然,这只是一种方法来实现这一目标。