2009-03-03 25 views
1

大家好,我正在使用CodeIgniter PHP framework開發一個照片共享網站。這個想法是,人們可以上傳他們的照片,管理他們(通過某種文件瀏覽器,允許他們創建子文件夾,拖動文件等),並編輯它們(一些基本的東西,如調整大小,旋轉和裁剪開始,以及稍後,我將添加一些高級功能)。從其用戶保護PHP文件管理器

我已經爲CI(Redux Authentication 2 Beta)實施了第三方身份驗證解決方案,現在我正在集成JS/PHP文件管理器(AjaxExplorer),但問題在於管理文件的PHP後端(移動,複製等)對ajax調用的用戶輸入過於信任。例如,它在做這樣的事情(簡化清楚起見):

move_uploaded_file($_FILES['upload']['tmp_name'], $root.$username.$_POST['destination_dir']); 

正如你所看到的,有明顯的安全問題,因爲它盲目地接受任何路徑的用戶拋出了!我已經可以看到有人發送類似「../AnotherUser/」的值作爲$ _POST ['destination_dir']的值。

我的問題是:什麼是「沙盒」用戶的最佳方式,以便只允許他管理自己的數據?我只是驗證+過濾輸入,希望抓住每一次入侵的企圖?有沒有專門解決這個特定問題的庫/包?

我認爲這個問題必須在任何(足夠成熟的)項目中解決,這使得用戶可以通過網絡瀏覽器管理他們的文件,所以我期望找到一些明確的指導方針(因爲有一個很多關於SQL注入,XSS,CSRF等),但我想我沒有使用正確的關鍵字。

回答

6

什麼是最好的方式,「沙箱」用戶,爲了只讓他管理自己的數據?

允許用戶想要的任何文件名/目錄名稱,但不要在服務器端文件系統上使用它們。相反,使用主鍵將路徑名寫入數據庫,並在主存儲目錄中使用主鍵作爲「34256.dat」的文件名(如果您願意,甚至可以將其用作數據庫中的BLOB)。然後通過下載腳本或URL重寫進行提供,以使所需的文件名顯示在URL中。

消毒傳入的文件名是。檢測'..'只是一個開始。太長的文件名;太短的文件名;前導和尾隨點的組合;領先和尾隨空白的組合;不同平臺的不同目錄分隔符;在某些平臺上無效的字符;控制字符; Unicode字符以及解決它們的環境特定方式;美國存托股份;文件名('.htaccess')或擴展名('.php','.cgi'),可能對您的Web服務器是「特殊」的; Windows的保留文件名...

您可以花費一輩子在各種平臺上追蹤有趣的小文件路徑規則,或者您可以忘記它並使用數據庫。

0

我不確定你的destination_dir是什麼樣的,但我想到的是分配目錄鍵,然後根據該鍵獲取目錄。例如:

//$_POST['destination_dir'] = '4hg43h5g453j45b3'; 
*_query('SELECT dir FROM destinations WHERE key = ? LIMIT 1'); //etc. 

但是,您必須事先預先定義按鍵。另一種選擇可能是相反的:md5/sha1輸入並將其用作destination_dir,然後使用關聯的標籤將該密鑰存儲在數據庫中。

0

沒有我知道的圖書館。
但是,在您的特定示例中,從字符串中除去所有(後)斜槓和圓點,然後在其末尾附加斜槓,這樣用戶無法更改文件夾。

$destdir = str_replace(array('.', '/', '\\'), '', $_POST['destination_dir']); 
$destdir .= "/"; 
+0

具有所有無效字符的字符串被映射到服務器根文件夾。 – bobince 2009-03-03 21:10:45

+0

感謝您的回答,但是至少在* NIX世界中,AFAIK點,斜槓和反斜槓都是可以接受的命名文件夾的字符。 – lima 2009-03-03 21:12:04