动态包含安全 [英] Dynamic Include Safety
问题描述
有没有办法安全地包含页面而不将它们全部放入数组中?
<预>if (preg_match('/^[a-z0-9]+/', $_GET['page'])) {$page = $_GET['page'].".php";$tpl = $_GET['page'].".html";if (file_exists($page)) 包含($page);如果(文件存在($ tpl))包含($ tpl);}我应该添加什么才能使它非常安全?
我这样做是因为我不喜欢必须包含必须包含在所有页面上的内容.包含页眉> 内容> 包含页脚"方式.我也不想使用任何模板引擎/框架.
谢谢.
您当前实施的弱点在于……
- 正则表达式只是测试字符串的开头,所以
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');如果 ($page && $tpl) {包括 $page;包括 $tpl;} 别的 {//记录错误!}} 别的 {//记录错误!}
注意:如果文件存在,realpath
返回给定相对路径的绝对路径,否则返回false
.所以 file_exists
不是必需的.
Is there any way to safely include pages without putting them all in an array?
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); }
What should I add to make this pretty safe?
I'm doing it this way bacause I don't like having to include stuff that has to be included on all pages. The "include header > content > include footer"-way. I don't wanna use any template engines/frameworks neither.
Thanks.
The weakness in your current implementation is that …
- the regular expression just tests the beginning of the string, so "
images/../../secret
" would pass, and - without further validation, "
index
" would also be a valid value and would cause a recursion.
To make your implementation safe, it’s a good practice to put everything, that’s intended to be included, in its own directory (e.g. "includes
" and "templates
"). Based on this, you just have to ensure that there is no way out of this directory.
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!
}
Note: realpath
returns the absolute path to the given relative path if file exists and false
otherwise. So file_exists
is not necessary.
这篇关于动态包含安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!