2009-11-02 48 views
1

我使用PHP語言進行文件上傳,並想知道我使用的以下方法是否安全?這個文件上傳方法是否通過PHP安全?

我使用簡單的方法進行文件上傳, 我從$ _FILES檢查文件名[「userfile的」] [「型」] ,然後,如果它有一個允許的文件擴展名,我上傳的文件與一些隨機數。 如果它是abc.zip,它可能會變成8w43x9d.zip。

請告訴我:這是一個非常糟糕的文件上傳方法嗎?

回答

2

隨機生成的安全文件名肯定是件好事。但是,如果您允許文件擴展名通過webroot,您仍然需要確保擴展名不會在服務器上造成任何問題,例如.php(好的,應該在Web服務器中禁用PHP處理上傳目錄,但仍然)。如果您位於Windows服務器上,也會出現問題,即尾隨點和空格會混淆文件系統;請確保您將擴展程序鎖定爲一些「已知正確」值。

不幸的是,['type']財產根本不能被依賴。有些瀏覽器不會填充內容類型,有些瀏覽器會放錯類型,因爲它們的操作系統設置很糟糕(一個臭名昭着的無用的IE瀏覽器默認調用JPEG image/pjpeg),有些瀏覽器總是會說application/octet-stream甚至text/plain

即使是['name']屬性也是不可靠的;除了說謊或模糊值的瀏覽器之外,給定類型在特定機器上總會有意想不到的文件擴展名。或者,對於Mac和Linux客戶端,完全有可能上傳的文件根本沒有擴展名(或者甚至可能對操作系統認爲的類型有錯誤的擴展名)。

所以是的,這一切都是一團糟。雖然從Content-Type提交或文件擴展名中嗅探類型可能對猜測文件的默認類型有用,但它完全不可靠,因此提供手動方法來選擇文件類型是一件好事。或者,如果您將上傳的文件作爲附件提供服務(例如,通過PHP腳本設置Content-Disposition: attachment),則通常只需調用application/octet-stream即可讓用戶在保存時將其排除。

如果您不作爲附件提供服務,則可能存在安全問題。 IE會高興地嗅探你爲<html>標籤提供服務的許多文件類型,並將這些文件視爲HTML,即使你告訴它它們是別的東西。然後它可以在瀏覽器中以內聯方式顯示它們,並讓它們將腳本注入安全上下文中。如果您的安全上下文中有任何重要內容,例如用戶帳戶和Cookie,那麼這是一個跨站點腳本安全漏洞。解決方法是作爲附件和/或從不在主站點安全上下文中的不同主機名提供服務(通常使用子域)。

允許你不完全信任的用戶上傳文件到你的服務器,這實際上比PHP教程中的簡單示例代碼會讓你相信更困難。 :-(

1

PHP Manual

$ _FILES [ 'userfile的'] [ '型']

的MIME類型的文件,如果瀏覽器提供了這個信息。一個例子就是「image/gif」。然而,這種MIME類型在PHP方面沒有被檢查,因此不會將其值視爲理所當然。

我不會相信任何用戶或用戶的瀏覽器發送給我的東西。

如果您正在嘗試學習,我會查看現有的安全來源,例如來自PEAR的HTTP_Upload。你甚至可以考慮使用Beta版本。

+1

感謝這一點,但您的鏈接是給404未找到錯誤! – user153887 2009-11-02 19:40:03

+0

對我的作品......沒有'ca2.'前綴的作品,也。鏈接*沒有被破壞,它可能在你的結尾被阻止。 – pavium 2009-11-02 19:56:22

+0

PEAR鏈接是404也是。 – 2009-11-02 21:02:42

0

除了上述文章中,我們依靠FileInfoSplFileInfo,到目前爲止,它已被證明是滿足我們需要的最好的選擇。

0

OK,在圖像的情況下,我們可以使用getimagesize($_FILES['userfile']['tmp_name']); 和可以驗證他們,但什麼的ZIPRARPDF文件呢?