安全上傳要限制用途、大小與格式,驗證檔案內容、重新命名、隔離儲存、移除主動內容,並以安全回應標頭提供下載。
上傳功能把外部資料帶進伺服器
頭像、附件、履歷與後台素材看似一般功能,但檔案可能偽裝類型、夾帶主動內容、耗盡儲存空間,或在可執行目錄中被伺服器當成程式。風險取決於檔案之後如何儲存、解析與提供,而不只是上傳瞬間。
先定義業務真正需要的格式與最大尺寸。允許清單越小,後續驗證與維護越可靠。
不要只相信檔名與瀏覽器 MIME
檔名、副檔名與用戶端 Content-Type 都可偽造。伺服器應檢查允許的副檔名、宣告 MIME、檔案簽章與實際解析結果是否一致。對壓縮檔還要限制解壓後總大小、檔案數量、巢狀深度與路徑穿越。
拒絕雙重副檔名、控制字元、尾端空白與伺服器可能特殊解讀的名稱。不要嘗試列出所有危險副檔名;以允許清單為主。
重新命名並放在不可執行的位置
上傳後由伺服器產生隨機檔名,原始名稱只作為經清理的顯示資訊。檔案應放在 Web Root 外,或使用獨立物件儲存/靜態網域,明確禁止 PHP、CGI、HTML、JavaScript 等主動內容執行。
下載時由授權邏輯判斷存取者,設定正確的 Content-Type、X-Content-Type-Options: nosniff 與必要的 Content-Disposition: attachment。敏感附件不應放在可猜測的公開網址。
圖片與文件需要安全轉換
圖片可使用受維護的函式庫解碼後重新輸出,移除不需要的 EXIF 與嵌入資料,並設定像素與記憶體上限。SVG 是 XML 主動內容,若非必要就不接受;若必須接受,需使用專用 sanitizer,移除 script、事件屬性、外部引用與危險 URL。
PDF、Office 與影音檔解析器都可能有漏洞,應在隔離環境中處理並維持更新。防毒掃描可增加偵測能力,但不能取代格式限制與隔離。
限制資源與濫用
同時限制單檔大小、請求大小、帳號配額、上傳速率與並行數。暫存檔要有自動清理機制,解析失敗或掃描逾時應預設拒絕。對公開分享連結設定到期與撤銷能力。
記錄上傳者、時間、最終檔案識別碼、驗證結果與處理狀態,但不要把檔案內容或敏感原名大量寫入日誌。
測試清單
- 合法格式但錯誤副檔名,以及合法副檔名但錯誤內容。
- 超大尺寸、巨大像素、截斷檔、損毀檔與壓縮炸彈。
- 同名檔、特殊字元、路徑符號與雙重副檔名。
- 未授權使用者讀取、替換或刪除他人附件。
- 上傳後的檔案是否能以 HTML、SVG 或程式形式執行。
測試使用自建無害樣本,不要把真實惡意程式投放到正式環境。
