2013-04-20 55 views
1

使用$_SERVER['REQUEST_URI']包含文件是否存在安全风险?你能通过请求uri以某种方式通过../../..吗?PHP包含基于REQUEST_URI

我在想什么是这样的:

<?php 
$path = $_SERVER['REQUEST_URI']; 
$path = preg_replace('~\\.html?$~', '.php', $path); 
include $path; 
?> 

这应该代替“热媒”或“.PHP”路径名“.html” URI和使它们。但我担心这里的安全。

+0

如何将请求的URI会是什么样子,你如何映射请求的路径,你的PHP文件? – Gumbo 2013-04-20 21:11:08

+0

你可以在request_uri中传递任何你想要的东西,包括html/javascript。这取决于您和您的代码以确保安全使用该值。您应该**永远不要**允许用户指定将用于包含/需要的路径,无论您认为安全性有多好。就像现在这样,他们碰到了'http://yoursite.com/http:// malicioussite.com/remote_takeover.php',它以文本格式输出php代码,并且您的服务器完全被彻底颠覆。 – 2013-04-20 21:15:53

+0

你的代码看起来并不像你特别关心它的安全性。这是允许用户注入数据的一个很好的例子。至少要对白名单进行过滤,并找到更多的无法注入无效路径的对策。是的,您可以通过请求URI传递点。这是一个标准变量,只是设置或取消设置。 – 2013-04-20 21:36:12

回答

3

$_SERVER['REQUEST_URI']包含请求的URI路径和查询字符串,因为它出现在HTTP request line中。因此,当请求http://example.com/foo/bar?baz=quux并且服务器将请求传递给脚本文件/request_handler.php时,$_SERVER['REQUEST_URI']仍然是/foo/bar?baz=quux。我用mod_rewrite的任何请求映射到request_handler.php如下:

RewriteEngine on 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteRule^/request_handler.php 

所以正确性,在文件系统路径中使用$_SERVER['REQUEST_URI']之前,你需要摆脱查询字符串。您可以使用parse_url这样做:

$_SERVER['REQUEST_URI_PATH'] = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); 

但由于该值从没有事先路径解析HTTP请求行来直接,但它仍然会含有类似..象征性的路径段。

但是,由于所请求的URI路径已经是绝对路径引用,并且请求http://example.com/etc/passwd应导致包含/etc/passwd,所以甚至不需要路径遍历。

所以这实际上是一个local file inclusion vulnerability

现在要解决这个问题,需要一个使用method的特定根目录,这是你的一个很好的改进。但你实际上需要$basedir前缀是:

$path = realpath($basedir . $_SERVER['REQUEST_URI_PATH']); 
if ($path && strpos($path, $basedir) === 0) { 
    include $path; 
} 

该解决方案提供了一些承诺:

  • $path是一个有效的,解决了现有的文件,或false路径;
  • 只有在$basedir$path的前缀路径时才会包含该文件。

但是,这仍然允许访问使用其他种类的access control like the one provided by Apache’s mod_authz_host module保护的文件。

0

这实际上并没有回答这个问题...

注意,您可以确保请求URI指向当前工作目录的实际有效的文件路径。您可以使用realpath函数来规范路径。

下面的代码会做的伎俩:

<?php 
$basedir = getcwd(); 

$path = $_SERVER['REQUEST_URI']; 
$path = preg_replace('~\\.html?$~', '.php', $path); 
$path = realpath($path); 

if ($path && strpos($path, $basedir) === 0) { 
    include $path; 
} else { 
    return false; 
} 
?> 

在这里,我用strpos验证$path开始与$basepath。由于realpath将删除任何有趣的业务../../..,这应该安全地保持在$basepath目录中。

0

确实不检查基本路径之前信任$ _ SERVER [“REQUEST_URI”]。

而且不要让一个过滤器,去除../从路径攻击者可以制作一个的Nieuw方式注入,如果他们了解过滤器理线。

0

我有同样的问题,选择了做以下的基础上自己甘博的回答

$_SERVER['REQUEST_URI_PATH'] = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); 

$path = realpath(FOLDER_ROOT . $_SERVER['REQUEST_URI_PATH']); 

$directory_white_list_array = array('/safe_folder1', '/safe_folder1/safe_folder2'); 

if ($path && strpos($path, FOLDER_ROOT) === 0 && (in_array(dirname($path), $directory_white_list_array) && ('php' == pathinfo($path, PATHINFO_EXTENSION)))) { 
    include $path; 
}else{ 
    require_once FOLDER_ROOT."/miscellaneous_functions/navigation_error.php"; 
    navigation_error('1'); 
} 

摘要: 添加目录白名单和PHP扩展的限制。