文件上傳漏洞是指網絡攻擊者上傳了一個可執行的文件到服務器上,當開發者沒有對該文件進行合理的校驗及處理的時候,頗有可能讓程序執行這個上傳文件致使安全漏洞。大部分網站都會有文件上傳的功能,例如頭像、圖片、視頻等,這塊的邏輯若是處理不當,很容易觸發服務器漏洞。這種漏洞在以文件名爲 URL 特徵的程序中比較多見。嗯,是的說的就是世界上最好的語言 PHP。例如用戶上傳了一個 PHP 文件,拿到對應文件的地址以後就能夠執行它了,其中的危害天然不言而喻。那在 Node.js 中就沒有文件上傳漏洞了麼?答案確定是否的。除了可執行文件外,還有如下幾個潛在的問題。html
用戶上傳的文件裏有兩個東西常常會被程序使用,一個是文件自己,還有一個就是文件名了。若是文件名被用來讀取或者存儲內容,那麼你就要當心了。攻擊者頗有可能會構造一個相似 ../../../attack.jpg
的文件名,若是程序沒有注意直接使用的話頗有可能就把服務器的關鍵文件覆蓋致使程序崩潰,甚至更有可能直接將 /etc/passwd
覆蓋寫上攻擊者指定的密碼從而攻破服務器。git
有些同窗可能會說了,/
等字符是文件名非法字符,用戶是定義不了這種名字的。你說的沒錯,可是咱們要知道咱們並非直接和用戶的文件進行交互的,而是經過 HTTP 請求拿到用戶的文件。在 HTTP 表單上傳請求中,文件名是做爲字符串存儲的。只要是合法的 HTTP 請求格式,攻擊者能夠構造請求中的任何內容用於提交給服務器。github
POST /upload HTTP/1.1
Host: test.com
Connection: keep-alive
Content-Length: 4237161
Accept: */*
Origin: http://test.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary9pQqgBGwpDfftP8l
Referer: http://test.com
Accept-Encoding: gzip, deflate
Accept-Language: en,zh-CN;q=0.9,zh;q=0.8,zh-TW;q=0.7,da;q=0.6
------WebKitFormBoundary9pQqgBGwpDfftP8l
Content-Disposition: form-data; name="file"; filename="../../attack.jpg"
Content-Type: image/jpeg
------WebKitFormBoundary9pQqgBGwpDfftP8l--
複製代碼
雖說 Node.js 在文件上傳服務端可執行程序的漏洞沒有 PHP 那麼高,可是除了服務端可執行以外咱們還有客戶端可執行問題,因此仍是要作好防備。假設用戶能夠上傳任意格式的文件,而若是攻擊者上傳了 HTML 文件後能夠配合 CSRF 攻擊進一步製造 XSS 攻擊。安全
若是你是一個圖片上傳的接口,若是你僅限制 HTML 格式的話也存在問題,由於圖片中有一種特別的存在是 SVG 格式。SVG 是一種矢量圖形格式,它使用 XML 來描述圖片,在其內部咱們是能夠插入 <html>
, <style>
, <script>
等 DOM 標籤的。若是不對 SVG 中的文件內容進行過濾的話,也會發生意想不到的效果。bash
<svg viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<script>alert(111)</script>
<rect x="25" y="25" width="50" height="50" />
</svg>
複製代碼
咱們知道在操做系統中軟鏈本質上也是一種文件,只是這個文件中不包含實際的內容,它包含另一個文件的路徑名。能夠是任意文件或目錄,能夠連接不一樣文件系統的文件。若是攻擊者上傳了一個軟鏈文件,軟鏈描述對應的是 /etc/passwd
的話,攻擊者利用程序能夠直接讀取到服務器的關鍵文件內容,致使服務器被攻陷。服務器
除了文件自己的問題以外,還有一種狀況咱們須要考慮到的是文件上傳以後的處理。若是咱們將用戶上傳的文件存儲到了本地,而沒有限制用戶的上傳頻率的話,就頗有可能被攻擊者利用。攻擊者會頻繁的上傳文件致使服務器磁盤佔用 100%,撐爆服務器以後沒辦法處理程序的其它任務進而致使服務器宕機。網絡
針對以上幾個可能出現的漏洞場景,咱們須要作到如下幾點:svg
Content-Type
字段,由於這兩個是用戶上傳內容,都是可被構造的。最好是經過文件頭的魔術數字來讀取,配合白名單列表就能避免這方面的問題。比較著名的使用魔術數字來判斷文件類型的模塊是 github.com/sindresorhu…,推薦直接使用。.svg
格式圖片的話,須要針對 SVG 內容進行 HTML 解析,過濾掉 <script>
, <foreignObject>
等相關標籤。固然,使用白名單的話是最好不過的了。這裏提供一個比較全的 SVG 合法標籤白名單列表。須要額外提醒的是,若是用戶上傳的壓縮包,程序有解壓的行爲,那麼不只要按照上述規則校驗壓縮包自己,還須要按照相同的邏輯校驗解壓以後的全部內容。同時針對服務器磁盤被撐爆的狀況,推薦限制用戶的上傳頻率下降風險,同時增長磁盤監控告警實時關注線上服務器的狀態。若是存儲到本地不是必須的話也可使用外部存儲服務來下降服務器這塊的風險。網站