2013-05-27 117 views
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中它会创建一个无限循环。据我所知,您无法加载外部网址。

例子:

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

但我真的不知道,有什么建议?或者是否可以使用?

+5

http://php.net/manual/en/security.filesystem.nullbytes.php – zerkms

+0

你应该看看Apache的['mod_rewrite'](http://httpd.apache.org/docs/current/mod /mod_rewrite.html),而不是(假设你使用的是Apache)。 –

+0

@Matt Browne,如果他不使用Apache?还有一些其他Web服务器比Apache好得多。 –

回答

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授权。

0

首先,根据URL参数包含页面是不安全的,这很容易被用户搞砸,所以最好避免这种情况。

第二,如果你想避免包括外部URL,您可根据需要http://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-include

如果你不是还在为配置的php.ini配置的php.ini,您可以修剪的“http:/ /“,”https://“字符串首先在$ _GET ['page'],这是一个很好的行为,并且使得一个.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崩溃会导致很多不好的事情。例如,您可以上传不会被删除的临时文件。这最终可能导致巨大的泄漏和攻击。

2

使用../../模式结合空字节可能导致路径“逃脱”其机箱。

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

有两件事情,你可以做些什么:

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

  2. 首先对路径进行消毒,例如,

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

我将导致到被称为本地文件包含一个严重的漏洞,该GET参数进行过滤更好,因为杰克提及或简单地使用PHP realpath()功能这是一个有点简单过滤。