2011-11-16 33 views
4

請求清理$_GET['']的最佳方法是什麼?我想只允許從一個目錄下載文件。

$baseDir = "/home/html/xy.com/public_html/downloads/";  
$path = realpath($baseDir . $_GET['file']); 

下一步是什麼?

+1

那你應該絕對不允許'..' –

+0

這是全部嗎?之後,我的腳本將是安全的? – Adrian

+0

不,不允許使用'/'和其他文件中不存在的字符。 – jli

回答

13

這裏是我會在行之後你有沒有:

if (dirname($path) === $baseDir) { 
    //Safe 
} 

http://php.net/dirname

基本上,做發送任何該文件實際上是在你支持一個路徑前的檢查。請注意,您還必須在文件名前($path)添加自己的/,並將其從$baseDir定義中刪除,因爲dirname()不會留下尾隨路徑分隔符。

+0

我必須在路徑中禁用「/」,「..」和其他字符,否則在此之後不需要?謝謝。 – Adrian

+3

@阿德里安,你應該真的明白這是如何工作的,然後再繼續。如果你不這樣做,你的腳本有可能會變得危險。我的方法確保'$ path'中文件的路徑與'$ baseDir'中指定的路徑相同。如果有人使用'..'或'/',那麼這些路徑將不再匹配。因此,這是安全的。你理解這一點很重要。如果您正在檢查多個目錄,則問題會變得更加複雜。 – Brad

+0

+1對於Brad的評論。理解你需要對文件系統訪問極其偏執是至關重要的。 – toon81

3

而不是後檢查沒有相對路徑碎片存在,更容易馬上剝離它們。只需使用basename()立即當你獲取值:

$baseDir = "/home/html/xy.com/public_html/downloads/";  
$path = realpath($baseDir . basename($_GET['file'])); 

已經保證它不能從基本目錄中向上或向下移動。

+0

謝謝,我把這個與Brad的解決方案結合起來。 :) – Adrian

+0

如果'../'在$ _GET中輸入,該怎麼辦? –

+0

@tazotodua如果你閱讀關於使用'basename()'的答案呢? – mario