2013-04-20 66 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擴展的限制。