安全漏洞?

时间:2013-05-27 02:34:40

标签: php security

使用此代码会产生什么影响?

<?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

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

5 个答案:

答案 0 :(得分:2)

正如zerkms已经指出的那样,根据PHP版本,file_existsinclude可能会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"

你可以做两件事:

  1. 使用您愿意接受的可能值的白名单。

  2. 首先清理路径,例如

    $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()函数,这有点简单。