ASP.NET MVC 5 實作更安全的檔案下載功能 (ASP.NET MVC Safer Downloads Implements)


  1. 目錄
    1. 問題說明
    2. 伺服器端
      1. 禁止上層目錄 Parent Path Disable
      2. 查詢字串篩選 Query String Filter
    3. 程式碼端
      1. HttpUtility UrlEncode
      2. AntiXssEncoder UrlEncode
      3. 檔案名稱使用 Guid 或 Hashed Value
  2. 後續行動

OWASP 中不當的設定會導致許多問題,例如檔案下載功能的實作上,如果沒有正確的設定,可能會衍生出 OWASP Top 10:2013 中的 Insecure Direct Object References,導致應用程式中機敏的檔案輕鬆地被惡意使用者取用 🐱‍💻

logo

目錄

問題說明

面臨惡意的檔案下載功能

public ActionResult File(string filename)
{
    string filePath = Server.MapPath($"~/Images/{filename}");
    return File(new FileStream(filePath, FileMode.Open), "text/plain", filename);
}

預設使用者可能會使用 localhost/Home/File?filename=hello.jpg 來存取檔案。但如果使用者惡意的將 query string 做手腳,調整為 localhost/Home/File?filename=../web.config 應用程式中的機敏檔案可能就暴露了!

伺服器端

伺服器端的處理不是最根本的處理,因為仍有可能因為開發上的漏洞讓惡意使用者有機可趁。但藉由伺服器端的調整,可以快速的且簡易的增加防禦面積,同時也能先中斷已知的惡意存取方式,在不中斷服務的前提下,爭取修正原始碼的時間 😉

禁止上層目錄 Parent Path Disable

查詢字串篩選 Query String Filter

如何透過 IIS 的 Request Filtering 功能限制存取特定檔案或副檔名
IIS7 篩選規則

程式碼端

HttpUtility UrlEncode

藉由 UrlEncode 的方式,可以將 query string 的內容加以編碼,能夠避免不當的字元被使用。

using System.Web;
var fileNamePath = HttpUtility.UrlEncode(queryString);

MS Docs - HttpUtility.UrlEncode

AntiXssEncoder UrlEncode

使用 AntiXssEncoder 則更進一步的會針對更多的特殊字元加以編碼。

using System.Web.Security.AntiXss;
var fileNamePath = AntiXssEncoder.UrlEncode(queryString);

MS Docs - AntiXssEncoder.HtmlEncode

檔案名稱使用 Guid 或 Hashed Value

高級打字員的技術雲- 如何防範Path Traversal目錄瀏覽漏洞
TPIU - Path traversal、Heap Inspection

後續行動

  1. 驗證 IIS 處理常式如何限制副檔名
  2. 驗證 ASP.NET 回應檔案使用的權限與 IIS 處理常式回應檔案使用的權限差別
  3. 擴充實作更安全的檔案下載方式:
  • Verify Authrization (Own Auth By Downloader : NTFS / Shares / DB)
  • Verify File Exists
  • new DirectoryInfo(directoryPath).EnumerateFiles()