0
<?php
if (preg_match('/^[a-z0-9]+$/', $_GET['p'])) {
$page = realpath('pages/'.$_GET['p'].'.php');
$tpl = realpath('templates/'.$_GET['p'].'.html');
if ($page && $tpl) {
    include $page;
    include $tpl;
} else {
    include('error.php');
}
}
?>

你会说这有多安全?

4

7 回答 7

2

我将它用于模板文件,因此它可以包含“页面”,而不必将单个文件与大量函数/字符串/switch-cases/elseifs(随你选)或创建大量具有相同布局的文件混为一谈。

它检查包含目录的实际路径应该在和要包含的文件的实际路径,如果文件的实际路径以包含目录开头,则允许包含。

<?
#If you're worried about funky characters messing with stuff, use this
#preg_replace("/[^A-Za-z0-9_\-]+/","",$str);

if (isset($_REQUEST['page'])) {
    $path=realpath("../inc/page").DIRECTORY_SEPARATOR;
    $full_page=realpath($path.$_REQUEST['page'].".php");
    if (file_exists($full_page)&&(strpos($full_page,$path)===0)) {
        include($full_page);
    } else {
        echo "FAILED";
    }
}
?>
于 2012-09-11T00:07:40.697 回答
1

好吧,实际上realpath在这种情况下它不提供任何安全性。实际上,这种情况根本没有任何作用,因为include内部会扩展路径。您在这里的安全性实际上取决于preg_match. 但是请注意,您使用的正则表达式不允许您使用任何带有大写字母、下划线或破折号的页面。

无论如何,我不认为包含基于请求中传递的参数的文件是个好主意。如果您需要,您的设计有问题。

于 2009-03-28T15:20:13.883 回答
0

在这种情况下, realpath对您没有帮助,因为include可以将页面路径解析为同一文件,无论它是 realpath 还是原始相对文件。它“似乎”是有效的,但我个人不会相信那段代码。我确信有人想出了一种巧妙的方法来将空字符注入输入,从而对字符串终止造成严重破坏。

为了安全起见,您需要做的是保留所有允许的输入/页面的白名单(或黑名单,如果它恰好更适合,但更喜欢白名单)。

于 2009-03-28T14:11:01.333 回答
0

好像很安全......

但效率不高。在 MVC 中,您有控制器和视图目录预设和预先知道。做一个统计来检查视图/控制器是否存在是没有意义的。

于 2009-03-28T14:19:07.350 回答
0

realpath()在这种情况下实际上会产生一些影响,因为FALSE如果目标文件不退出,它将返回。但正如其他海报已经说过的那样——这不会给代码增加任何安全性。

在指定文件不存在的情况下,这是一种错误处理方式。

于 2009-03-29T10:40:22.080 回答
0

我无法评论 PHP realpath,但如果它只是系统 realpath 函数的包装器,那么需要注意一件事:在某些系统(例如 Solaris)上,如果进程在 realpath 执行时收到信号,它将返回空字符串...在这种情况下,您必须确保您的代码设置为处理这种情况(除非 PHP 实现为您解决了该特定困境)

于 2013-02-27T22:12:02.927 回答
0

更好地在 $_GET['p'] 上运行 basename()。肯定没有目录遍历攻击。

于 2009-04-03T09:34:40.303 回答