0

在我的 php 文件中,我使用 $_GET 参数在我的服务器上打开一个文件,如下所示:

$filename = $_GET["filename"];
$content = file_get_contents("/path_to_files/".$filename);

我的问题是,如何使这更安全,以便用户无法访问服务器上父文件夹中的文件?这是我需要在服务器上执行的操作,例如权限和/或配置吗?或者应该$filename在我的 php 文件中进行验证?提前致谢!

4

5 回答 5

5

最安全的方法是在使用文件路径时避免使用外部参数。您可以实现如下内容:

$files = array (
    'file1' => 'path/to/file1.php',
    'file2' => 'path/to/file2.php',
    'file3' => 'path/to/file3.php',
    ...
);

if ( in_array($_GET['file'], array_keys($files) ) )
{

    $content = file_get_contents($files[$GET['file']]);
}

否则...从这里检查方法: string sanitizer for filename

于 2013-09-18T06:40:59.237 回答
1

我认为您不必对服务器上的权限做任何事情,因为它实际上是访问文件的 php,而不是用户。

您可以根据文件白名单检查 $filename。你能提供更多关于你想要做什么的信息吗?

于 2013-09-18T06:39:47.070 回答
1

最好是为允许的文件设置“白名单”;

你可以有类似文件名模式的东西,[someName] [dot] [extension]

if (!preg_match('/^[a-zA-Z0-9_-]+\.[a-zA-Z0-9]+$/', $filename) {
   throw new Exception('file not allowed');
}

但是这样,用户可以访问/path_to_files/ 目录中的所有文件

于 2013-09-18T06:42:07.320 回答
1

您发布的方法不是一种非常安全的方法,您应该考虑更改它。

如果您需要使用此方法,请对您的脚本进行以下更改

$filename = basename($_GET["filename"]);
$content = file_get_contents("/path_to_files/".$filename, false);

file_get_contents 函数中的 false 参数只会在您提供的路径中查找文件,而不会在其他地方查找。

于 2013-09-18T06:52:35.253 回答
0

白名单似乎是最好的安全方式,但您可以使用这样的脚本

$file = realpath("/path_to_files/" . $_GET['filename']);
// Check that $file is actually in the specified path
if(substr($file, 0, strlen("/path_to_files/")) == "/path_to_files/"){
    include($file);
}

但我不知道是否有可能欺骗realpath ...

于 2013-09-18T10:57:46.290 回答