RealPath安全吗?

时间:2009-03-28 13:59:13

标签: php realpath

<?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');
}
}
?>

你觉得这有多安全?

7 个答案:

答案 0 :(得分:2)

我将它用作模板文件,因此它可以包含“页面”,而不必使用大量函数/字符串/ switch-cases / elseifs(选择)来填充单个文件,或者创建大量文件相同的布局。

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

<?
#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";
    }
}
?>

答案 1 :(得分:1)

嗯,实际上realpath在这种情况下不提供任何安全性。实际上,在这种情况下,它完全没有任何意义,因为include内部将扩大路径。您的安全性实际上取决于preg_match。但请注意,您正在使用的正则表达式不允许您使用带大写字母的任何页面,带下划线或短划线。

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

似乎是安全的......

但效率不高。 在MVC中,您可以使用控制器和视图dirs预设和预先知道。没有必要做一个stat来检查视图/控制器是否存在。

答案 4 :(得分:0)

在这种情况下,

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

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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