使用GET / POST数据的“require”是否安全?

时间:2012-07-26 19:42:15

标签: php security

使用以下代码是否安全:

require($_SERVER['DOCUMENT_ROOT'] . "/pages/" . $_GET['page'] . ".php") 

5 个答案:

答案 0 :(得分:12)

不,它不安全。为什么呢?

因为两个点的序列 /../ 意味着一个目录返回,攻击者可能在您的系统上包含任何内容,甚至高于$_SERVER['DOCUMENT_ROOT']。 (在一个不幸的配置中,这意味着秘密/敏感的OS配置文件。)

您必须IF或SWITCH以获取允许的值以防止恶意输入。例如:

switch($_GET['page']) {
     case 'welcome': $page='welcome';
     case 'shop': $page='shop';
     default: $page='index';
}
require($_SERVER['DOCUMENT_ROOT'] . "/pages/" . $page . ".php")

同时查看in_array()以便更轻松地过滤。

答案 1 :(得分:2)

StackOverflow有一个有用的Q& A,用于sanitize user input with PHP。它已经有几年了,但原则并没有改变。

快速回答是:如果你可以首先避免这个问题,那你就更好了。

告诉我们您是如何尝试使用此功能的,我们可能会提供改进建议。

答案 2 :(得分:1)

这不安全。您可以使用具有允许值的数组。 例如

$allowed_pages = array('index', 'test', 'my_page')
if (!in_array($_GET['page'], $allowed_pages)){
    echo 'good bye';
    die();
} else {
   //
}

答案 3 :(得分:-1)

如果您信任dir中的所有文件,请尝试:

if (in_array($_GET['page'],glob("/pages/*.php"))) {
   require($_SERVER['DOCUMENT_ROOT'] . "/pages/" . $_GET['page'] . ".php");
} else echo "Nice try hacker!";

这是另一个使用我用来清理上传文件名的函数部分的解决方案:

选项#2 谢谢Daniel,Rok!

$page = preg_replace('/[^a-zA-Z0-9_ %\[\]\.\(\)%&-]/s', '', $_GET['page']);
$filename = $_SERVER['DOCUMENT_ROOT'] . "/pages/" . str_replace("/",'',$page) . ".php";
if (file_exists($filename)) {
    require($filename);
} else echo "Nice try hacker!";

请注意,只有在文件名中没有特殊字符时才能使用此功能

答案 4 :(得分:-3)

使用regEx检查$_GET['page']