使用此代码会产生什么影响?
<?php
if(file_exists("pages/" . $_GET["page"] . ".php")){
include("pages/" . $_GET["page"] . ".php");
} else{
include("pages/home.php");
}
?>
我已经做到了这样你就不能在没有“.php”扩展名的情况下加载任何东西,所以我认为使用起来非常安全。如果您使用:
website.com/index.php?page=../index
在网址中,它会创建一个无限循环。据我所知,您无法加载外部URL。
示例:
website.com/index.php?page=anothersite.com/virus
但我不确定,有什么建议吗?或者这可以使用吗?
答案 0 :(得分:2)
正如zerkms已经指出的那样,根据PHP版本,file_exists
和include
可能会not be safe when handling NULL bytes。只有since PHP version 5.4.3, filesystem functions are said to be NULL byte safe。
因此,您应该在使用之前验证该值,例如,使用允许值的白名单:
$allowedPages = array(/* … */);
if (in_array($_GET["page"], $allowedPages)) {
// allowed
}
您还可以将此白名单展开到文档根目录下的任何现有文件:
if (strpos($_GET["page"], "\0") !== false) {
// NULL byte detected
}
$path = realpath("pages/" . $_GET["page"] . ".php");
$base = realpath($_SERVER['DOCUMENT_ROOT']) . "/";
if ($path !== false && substr($path, 0, strlen($base)) === $base) {
// allowed
}
但是,这仍然可以用于绕过其他访问控制措施,例如基于位置的HTTP授权。
答案 1 :(得分:2)
使用../../
模式与空字节组合可能会导致路径“转义”其机箱。
"../../../etc/passwd\0.php"
你可以做两件事:
使用您愿意接受的可能值的白名单。
首先清理路径,例如
$path = preg_replace('/[^a-z]/', '');
// now use $path as you would
答案 2 :(得分:0)
首先,根据URL参数包含页面是不安全的,这可能很容易被用户搞砸,你最好避免这种情况。
其次,如果你想避免包含外部网址,你可能需要根据http://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-include配置php.ini
如果你还没有进入配置php.ini,你可以先调整$ _GET ['page']中的“http://”,“https://”字符串,这是一个很好的行为,并创建一个 .htaccess 文件将未发送的页面请求重定向到home.php,您还必须确保mod_rewrite在您的服务器上。
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ home.php [NC,L]
答案 3 :(得分:0)
这样做,正如你所指出的那样可能导致无限循环的帽子会导致php崩溃。
Php崩溃可能会导致许多不好的事情。例如,您可以上传不会被删除的临时文件。这最终可能导致巨大的泄密和攻击。
答案 4 :(得分:0)
我将导致一个严重的漏洞,称为本地文件包含,GET参数未被过滤,更好地过滤它,如jack所提到的或只是使用php realpath()函数,这有点简单。