<?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');
}
}
?>
你觉得这有多安全?
答案 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实现解决了您的特定困境)