有没有办法安全地包含页面而不将它们全部放在一个数组中?
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。我也不想使用任何模板引擎/框架。
感谢。
答案 0 :(得分:6)
您当前实施的弱点是......
images/../../secret
”会通过,index
”也是有效值,会导致递归。为了确保您的实施安全,最好将所有要包含的内容放在自己的目录中(例如“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并参加一两个教程,你会喜欢它,因为你想要使用动态包含。