2014-01-08 58 views
0

我已收到其他人的系統代碼,該系統在瀏覽器中顯示包含照片的文件夾。PHP實時路徑無法阻止目錄遍歷

例如,這是在網站上的URL可能:

gallery.php?action=view&folder=Cars 

此刻,你可以將「汽車」與../../../../../,它將高興地顯示Linux根文件夾。幸運的是,該網站目前處於離線狀態。

我嘗試使用真實路徑來解決這個問題。這是我到目前爲止有:

case 'view' : 
$name = realpath(dirname(__FILE__) . "/Content/Gallery/" . $_GET['folder']); 

echo $name; 

$data = $file->getPictures($name); 
require 'Views/Gallery.view.php'; 
break; 

我已經加入回聲在第三行看到的網址是什麼。在上面的網址,一切都很好,回聲輸出:

/var/www/Content/Gallery/Cars 

到目前爲止,這麼好。但是,如果我輸入/../../../../../../../../而不是「Cars」,則$ name將變爲/並且頁面仍顯示根文件夾。英語不是我的第一語言,所以我可能會誤解實際路徑的工作方式或做法。根據我的理解,它會從給定的URL中刪除../的任何實例。

有人可以告訴我我做錯了什麼嗎?

+1

的[防止目錄遍歷在PHP,但允許路徑(可能重複http://stackoverflow.com/questions/4205141/prevent-directory-traversal-in-php-but-allowed-paths) –

+1

這就是爲什麼PHP會得到一個糟糕的說唱:\ –

+0

@Mike爲什麼? 'realpath()'不是爲了對抗目錄遍歷攻擊而設計的;也沒有聲稱這樣做 –

回答

1

從我的理解,它從一個給定的URL中移除任何../實例。

不,這不是它做什麼。它不是用於URL,而是用於路徑。它只是轉換路徑並將../擴展到正確的文件夾中。它不會移除它們,它可以解決它們 - 這意味着它會計算../所代表的內容,並改變實現該目標的路徑。

它也改變/到\ Windows上。

realpath

的realpath()擴展所有的符號鏈接並解決引用輸入路徑「/./」,「/../」以及多餘的「/」字符並返回規範化的絕對​​路徑。

+0

謝謝,我對該頁面上的示例感到困惑。在那裏,一個例子輸出「echo realpath('./../../ etc/passwd');」作爲「/ etc/passwd」。那麼我該如何停止目錄遍歷呢? – ohyeah

+0

再次閱讀示例。在此之前,它移動到一個目錄。相對於那個目錄,'./../../ etc/passwd'可以轉換成'/ etc/passwd' – Jessica

6

realpath()單獨不足以打擊目錄遍歷。

你描述的是exaclty什麼它的設計做到:像../相對的東西轉化爲實際的目錄路徑。

但是,爲了安全起見,您可以採取realpath() ed路徑並參見它是否仍然是安全基路徑的子節點。如果不是,有人試圖潛入一個目錄,他們沒有業務爲:

$name = realpath(dirname(__FILE__) . "/Content/Gallery/" . $_GET['folder']); 

// The safe root directory. 
$safe_root = dirname(__FILE__) . "/Content/Gallery/"; 

// Check whether realpath() result is still inside /Content/Gallery 
if (substr($name, 0, strlen($safe_root)) != $safe_root) 
    die ("Possible directory traversal attack");