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

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

4

5 回答 5

2

使用../../与空字节组合的模式可能会导致路径“逃脱”其外壳。

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

你可以做两件事:

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

  2. 首先清理路径,例如

    $path = preg_replace('/[^a-z]/', '');
    // now use $path as you would
    
于 2013-05-27T05:36:31.417 回答
2

正如zerkms已经指出的那样,取决于 PHP 版本,在处理 NULL bytesfile_existsinclude可能不安全。仅从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 授权。

于 2013-05-27T05:27:55.933 回答
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] 
于 2013-05-27T02:58:56.970 回答
0

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

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

于 2013-05-27T03:03:47.300 回答
0

我将导致一个严重的漏洞,称为本地文件包含,GET 参数没有被过滤更好地过滤它,正如 jack 提到的那样,或者只是使用有点简单的php realpath()函数。

于 2013-05-27T13:19:06.063 回答