安全漏洞?

4
使用这段代码的后果是什么?
<?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中会创建一个无限循环。据我所知,你无法加载外部URL。

例子:

website.com/index.php?page=anothersite.com/virus

但我不是很确定,有什么建议吗?或者这样使用是否可以?

5
好的,请告诉我需要翻译的具体内容。 - zerkms
如果你使用的是Apache服务器,建议你查看一下Apache的mod_rewrite模块。 - Matt Browne
@Matt Browne,如果他不使用Apache呢?还有一些其他的Web服务器可用,它们比Apache更好。 - Roman Newaza
然后您可以回到Apache手册中了解详细信息。 - Matt Browne
@RomanNewaza 几乎所有的共享 Web 主机都运行在 Apache 上,仍有大量网站运行在共享主机上。我相信与以前相比,在虚拟/专用主机上使用 Apache 的情况并不像以前那样普遍... - Matt Browne
显示剩余6条评论
5个回答

2
正如zerkms所指出的那样,根据PHP版本,file_existsinclude在处理NULL字节时可能不安全。只有自PHP版本5.4.3以来,文件系统函数被认为是NULL字节安全的
因此,在使用值之前,您应该对其进行验证,例如,使用允许值的白名单:
$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授权的访问控制。

2

使用../../模式与空字节组合可导致路径“逃脱”其包围。

"../../../etc/passwd\0.php"

对此,您可以采取以下两种措施:

  1. Use a white list of possible values you're willing to accept.

  2. Sanitize the path first, e.g.

    $path = preg_replace('/[^a-z]/', '');
    // now use $path as you would
    

0
首先,根据URL参数包含页面是不安全的,因为用户很容易搞乱,最好避免这种情况。
其次,如果你想避免包含外部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] 

0

正如您所指出的,这样做可能会导致无限循环帽子,从而导致 PHP 崩溃。

PHP 崩溃可能会导致许多不良后果。例如,您可以上传不会被删除的临时文件。这最终可能导致巨大的泄漏和攻击。


0

我会导致一个严重的漏洞,称为本地文件包含漏洞,GET参数没有被过滤,最好按照Jack所提到的进行过滤,或者简单地使用php realpath()函数,这个函数比较简单。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接