2011-01-10 74 views
0

我有一個PHP腳本,它允許用戶通過指定文件名來刪除目錄中的某些文件(通過下拉菜單 - 但對於惡意更改的人來說這很容易) 。我「清洗」通過執行以下操作允許在目錄中訪問文件的安全字符

if(preg_match(/'/^[a-zA-Z0-9.]$/'/,$file)) { 
    # do stuff to this particular file 
} 

我相當肯定應該阻止任何人起牀到什麼討厭的文件名,但這裏的人有大量的知識更多的話,我,我想我會問 - 這裏有沒有一個洞,還是這會讓這種討厭的東西消失?

回答

2

我不確定你的正則表達式是否真的有幫助:在該範圍之外有有效的字符,你將無法以這種方式刪除。

我要做的一件事是在完整的最終路徑上執行realpath(),並檢查它是否仍然是允許的文件路徑的子項。這將阻止../../目錄遍歷攻擊,即使它們使用了一些特殊字符。這應該已經提供了相當好的安全性。

您還可以額外使用掃描​​3210目錄和檢查結果看,所請求的文件是否確實是在那裏(那是不可能的,即使是最偷偷摸摸的目錄遍歷規避。)

如果你想對此,你可以完全使用另一種方法:不要傳輸文件名,而是列出你以前指定的列表索引。例如,如果你表明這個名單的用戶,並將其保存在臨時文本文件或數據庫記錄:

  1. 的Readme.txt
  2. 許可證
  3. 的Readme.doc

,然後通過只有文本文件或數據庫記錄的(隨機)ID以及要刪除的文件的編號:

delete.php?list=xasdafdas&index=3 

you shou對於任何可能的注入和文件名稱篡改,ld都有一個無懈可擊的解決方案。

您將不得不爲每個請求存儲單個列表,因爲這些文件可能會更改。

+0

我只是擔心他們離開那個目錄。該目錄中的任何內容都是公平的遊戲,這些文件只能有a-z,A-Z,0-9和。在文件名中。我想知道如果我只允許這些角色出現在目錄中或者破壞真正的破壞時,是否還有一些巧妙的方式。但是,是的,我同意,檢查提交的文件名與我想允許刪除的文件可能是最安全的。 – Will 2011-01-10 01:53:56

0

也許你應該改變你的正則表達式中

if(preg_match(/'/^[^a-zA-Z0-9.]+$/'/,$file)) { 
# do stuff to this particular file 
} 
+0

是的,我有regEx錯誤(所以你實際上)應該是:`/^[a-zA-Z0-9。] + $ /`但問題仍然存在 - 有人仍然可以做一些令人討厭的那些有效的字符? – Will 2011-01-10 01:37:30

0

如果你的文件名不是絕對路徑,而你總是前綴的目錄路徑

chdir(...); // change directory to that directory 

// make use the $file is not contains '/' 
$file = basename($file); 

// check $file is not in list of files that you don't allow for delete 
if ($file=='index.php' ...) 
{ 
    // do nothing 
    return false; 
} 


if (is_file($file)) 
{ 
    unlink($file); // or other actions 
} 
0

這正則表達式匹配幾乎任何東西。你的意思是/^[a-zA-Z0-9.]/而不是?這仍然會匹配../../../etc/shadow之類的東西。 /^[a-zA-Z0-9.]+$/(或者簡單地/^[\w\d.]+$/)更好,或者您可以根據您創建的下拉列表檢查文件名。

相關問題