2011-05-14 35 views
7

我有這個問題一段時間:一個文件的MIME類型究竟是如何確定的?我相信這是通過檢查文件的特定字節是否包含任何已知的magic numbers/file signatures來完成的,對嗎?Mimetypes在上傳中的可靠性(PHP)

如果是這樣,這帶來了另一個問題,可以說,我上傳一個bash腳本用假GIF文件簽名,以一個網站,只允許上傳的圖片,有什麼事情發生?或者:

  1. 的MIME類型檢測程序是足夠聰明來檢測仿冒簽名,或
  2. image/gif被錯誤地返回作爲MIME類型和允許上傳繼續

我沒有一個HEX編輯安裝了ATM,我不喜歡從測試中形成安全相關的結論,因爲我可能會錯過(或誤解)某些內容,所以我的問題是:上述哪一個選項是正確的?

此外,是否有任何其他的最佳實踐(除了檢查的MIME類型),以確保任何給定的文件實際上是什麼,似乎/需要(或允許)是?提前致謝。

PS:要說清楚的是,我並沒有詢問$_FILES superglobal中的type索引。

回答

6

我的理解是在文件上傳代碼的MIME確定程序是非常粗糙,而$ _FILES數組中的MIME類型根本不能被信任。這是我的經驗,它很容易受到欺騙。

你最好使用Fileinfo庫,它提供更強大的文件類型檢測。

http://www.php.net/manual/en/ref.fileinfo.php

+0

'$ _FILES'中的'type'索引來自瀏覽器/用戶,根本不可信。我正在使用Fileinfo(或相似的),但問題仍然適用:如果MIME是僞造的,Fileinfo是否足夠聰明以檢測? – 2011-05-14 06:59:26

+0

就我從文檔中瞭解的內容而言,Fileinfo會查看標題,並執行一些啓發式操作來檢測文件類型,並且不需要(或依賴)瀏覽器發送的信息。 – 2011-05-14 07:26:10

+1

PHP手冊中的fileinfo頁面顯示文件檢測不是100%可靠的。我會假設你可以製作一個可以欺騙它的文件。 – GordonM 2011-05-14 07:32:47

-1

我的理解是,這個(脆弱的MIME類型)是文件名的,應通過各種手段進行加密時,他們上傳並存儲在數據庫中通過ID號進行檢索的原因。基本上應該有人設法上傳惡意腳本,他們永遠無法找到它來運行它?

+0

但是,存儲在數據庫或CDN上並不總是一種選擇。模糊文件名不能被認爲是安全的,並且具有丟失可能有價值的語義數據(文件名本身)的效果。我意識到架構選項和預防措施,但我的問題主要是針對MIME類型(錯誤?)檢測和可能的替代方案。 – 2011-05-14 07:02:37

2

如果你在談論$_FILES['userfile']['type']那麼這個信息是由瀏覽器發送。它可能會也可能不會存在,即使它現在您應該像對待任何其他用戶輸入一樣對待它。

如果你有興趣在檢查圖像,你可以使用和getimagesize函數來確定文件類型。對於無法理解的圖像,此函數返回NULL。即使它返回有效的圖片類型,您仍然可以拒絕該文件,例如如果你期待GIF和JPEG,而你卻得到了TIFF。

此外,網絡服務器將確定是否執行不依賴於文件的權限的文件(執行位和shebang行)和文件擴展名。如果你對這兩個人進行檢查,你可能沒問題。