动态包括安全性

时间:2009-02-08 00:58:41

标签: php security

有没有办法安全地包含页面而不将它们全部放在一个数组中?

if (preg_match('/^[a-z0-9]+/', $_GET['page'])) {

$page = $_GET['page'].".php";
$tpl = $_GET['page'].".html";
if (file_exists($page)) include($page);
if (file_exists($tpl)) include($tpl);

}

我应该添加什么才能让它变得非常安全?

我这样做是因为我不喜欢必须包含必须包含在所有页面中的内容。 “包含标题>内容>包括页脚”-way。我也不想使用任何模板引擎/框架。

感谢。

4 个答案:

答案 0 :(得分:6)

您当前实施的弱点是......

  1. 正则表达式只测试字符串的开头,因此“images/../../secret”会通过,
  2. 未经进一步验证,“index”也是有效值,会导致递归。

  3. 为了确保您的实施安全,最好将所有要包含的内容放在自己的目录中(例如“includes”和“templates”)。基于此,您只需确保没有办法退出此目录。

    if (preg_match('/^[a-z0-9]+$/', $_GET['page'])) {
        $page = realpath('includes/'.$_GET['page'].'.php');
        $tpl = realpath('templates/'.$_GET['page'].'.html');
        if ($page && $tpl) {
            include $page;
            include $tpl;
        } else {
            // log error!
        }
    } else {
        // log error!
    }
    

    注意:如果文件存在,realpath将返回给定相对路径的绝对路径,否则返回false。所以file_exists不是必需的。

答案 1 :(得分:4)

尽管你所说的不想在数组中存储可用页面列表,但它可能是最好的非db解决方案。

$availFiles = array('index.php', 'forum.php');
if(in_array($_GET['page'].".php", $availFiles))
 {
   //Good
 }
else
 {
   //Not Good
 }

您可以使用数据库查询或通过读取文件动态构建数组,甚至可以读取目录中的内容并过滤掉您不想要的内容。

答案 2 :(得分:1)

您绝不应将用户提供的信息用于包含。您应始终拥有某种请求处理程序来为您执行此操作。虽然正则表达式可能会过滤某些东西,但它不会过滤所有内容。

如果您不希望自己的网站被黑客入侵,则不允许用户通过指定包含来控制应用程序的流程。

答案 3 :(得分:0)

我同意Unkwntech。这是一种将文件包含到您的网站中的不安全方式,我希望PHP程序员可以完全取消它。即便如此,具有所有可能匹配的阵列肯定更安全。但是,您会发现MVC pattern效果更好,更安全。我会下载code igniter并参加一两个教程,你会喜欢它,因为你想要使用动态包含。