2024年3月8日 星期五

[研究]ASP.NET,Fortify SCA 報告 CreateDirectory(); 有 Path Manipulation 問題

[研究]ASP.NET,Fortify SCA 報告 CreateDirectory(); 有 Path Manipulation 問題

2024-03-08

環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C# + SQL Server 2019 + SQL Server Management Studio (SSMS) 19

********************************************************************************

【Fortify SCA報告】

Abstract:

攻擊者可以控制在 WebForm1.aspx.cs 中第 126 行的 CreateDirectory() 的檔案系統路徑引數,可讓他們存取或修改原本受保護的檔案。

Explanation:

當發生以下兩種情況的時候,會產生 path manipulation 錯誤:

1.攻擊者可以指定在檔案系統操作中所使用的路徑。

2. 攻擊者可藉由指定資源來取得一般情況下不被允許的權限。

例如,程式可能會讓攻擊者能夠覆寫指定的檔案,或是能夠在攻擊者控制的組態下執行。

在此案例中,攻擊者可以指定在 WebForm1.aspx.cs 中第 123 行的 get_AppSettings() 進入程式的值,而且可使用此值存取 WebForm1.aspx.cs 中第 126 行的 CreateDirectory() 的檔案系統資源。

範例 1:以下的程式碼使用 HTTP 要求的輸入建立一個檔案名稱。程式設計師沒有考慮到攻擊者能夠提供檔案名稱類似「..\\..\\Windows\\System32\\krnl386.exe」的可能性,這會導致應用程式刪除重要的 Windows 系統檔案。

String rName = Request.Item("reportName");

...

File.delete("C:\\users\\reports\\" + rName);

範例 2:以下程式碼使用來自配置檔案的輸入,來決定要開啟哪個檔案並返回給使用者。如果程式需要適當權限才能執行,且惡意使用者可以變更配置檔案,則他們可以使用程式來讀取系統中結尾副檔名為「.txt」的任意檔案。

sr = new StreamReader(resmngr.GetString("sub")+".txt");

while ((line = sr.ReadLine()) != null) {

Console.WriteLine(line);

}


********************************************************************************

【Fortify SCA報告】

Recommendations:

避免 Path Manipulation 的最佳方法是使用間接方法:建立合法值的清單,而使用者只能從清單中選取。使用此方法,使用者所提供的輸入就不會直接用來指定資源名稱。

但在某些情況下,這種方法是不切實際的,因為這樣一份合法資源名稱太過於龐大或是太難以維護。在這些情況下,程式設計師通常會實作拒絕清單。在使用輸入資料前,拒絕清單會選擇性的拒絕或避開可能有危險的字元。不過,任何此類不安全字元清單可能都不完整,並且幾乎肯定會過期。一個更好的方法是建立字元清單。此清單會列出允許出現於資源名稱中的字元,並僅接受由核准集中的字元組成的輸入。

Tips:

1. 如果您滿意程式執行自訂輸入驗證,請使用 Fortify Custom Rules Editor 為該驗證常式建立清楚的規則。

2. 實作有效的拒絕清單非常困難。如果驗證邏輯需要實作拒絕清單,應對驗證抱持懷疑的態度。在不同的作業系統、資料庫或其他資源中,不同類型的輸入編碼以及不同的中繼字元組可能會解譯成不同的意義。請確定如果這些要求有變更的話,拒絕清單是否可以輕鬆、正確、完整的更新。

3. 有許多現代的 Web 架構提供執行使用者輸入驗證的機制 (包括 ASP.NET 要求驗證和 WCF)。為了突顯未驗證的輸入來源,Fortify 安全編碼檢查規則會降低 Fortify Static Code Analyzer 所報告之問題的攻擊可能性,並在使用框架驗證機制時提供支援證據的指標,以動態重新排列其優先順序。如果是 ASP.NET 要求驗證,我們也會針對何時明確停用驗證提供證據。我們將此功能稱為「內容相關性排名」。為了進一步協助 Fortify 使用者進行稽核程序,Fortify Software 安全研發團隊提供了資料驗證專案範本,該範本會依據套用到其輸入來源的驗證機制,按資料夾對問題進行分組。

********************************************************************************

請問 ASP.NET, WebForm, Fortify SCA 報告 System.IO.Directory.CreateDirectory(fd); 有 Path Manipulation 問題,但 fd 是動態字串,如何解決?

if (!System.IO.Directory.Exists(fd))
{
  System.IO.Directory.CreateDirectory(fd);
}

ChatGPT

在這種情況下,您可以通過使用絕對路徑來消除潛在的路徑操作漏洞。您可以確保 fd 是一個絕對路徑,而不是相對於某個基本目錄的相對路徑。這樣做可以防止惡意使用者通過修改 fd 來操縱系統的文件系統。

以下是一種方法:

// 檢查是否為絕對路徑
if (Path.IsPathRooted(fd))
{
    // 確保路徑合法性
    if (!fd.Contains("..") && !fd.Contains(":"))
    {
        // 檢查目錄是否存在,如不存在,則創建之
        if (!Directory.Exists(fd))
        {
            Directory.CreateDirectory(fd);
        }
    }
    else
    {
        // 處理非法路徑的情況,例如包含 ".." 或 ":" 的路徑
        // 可以記錄日誌或採取其他適當的措施
    }
}
else
{
    // 處理相對路徑的情況,因為這可能會導致路徑操作漏洞
    // 可以記錄日誌或採取其他適當的措施
}


這樣當程式執行到 using 敘述的結尾時,StreamReader 會自動被關閉,確保資源被釋放。這能夠確保你的程式碼在執行時不會造成資源洩漏。

********************************************************************************

有無任何 NuGet 套件可以解決 ? 我是 ASP.NET, .NET Framework, WebForm

ChatGPT

有一個不需要安裝額外 NuGet 套件的解決方案。

在 .NET Framework 中,您可以使用 Server.MapPath 方法來將虛擬路徑轉換為實際文件系統路徑。這個方法會將虛擬路徑映射到伺服器上的實際路徑,並且會自動處理任何路徑操作漏洞。

這裡是如何使用 Server.MapPath 方法來創建目錄的示例:

// 將虛擬路徑映射到實際文件系統路徑
string physicalPath = Server.MapPath(fd);

// 檢查目錄是否存在
if (!Directory.Exists(physicalPath))
{
    // 創建目錄
    Directory.CreateDirectory(physicalPath);
}

這樣,您就可以在 ASP.NET WebForms (.NET Framework) 中安全地創建目錄,而不需要擔心路徑操作漏洞。

********************************************************************************

【實際測試】

Web.Config

<?xml version="1.0" encoding="utf-8"?>
<!--
  如需如何設定 ASP.NET 應用程式的詳細資訊,請前往
  https://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.8" />
    <httpRuntime targetFramework="4.8" />
  </system.web>
  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" />
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
    </compilers>
  </system.codedom>
  <appSettings>
    <add key="TempFolder" value="D:\Production\TempImageFiles\" />
  </appSettings>
</configuration>

Default.aspx.cs

using System;
using System.Configuration;
using System.IO;

namespace WebApplication1
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // Test 1
            string fd = (string)ConfigurationManager.AppSettings["TempFolder"] + @"\";
            if (!System.IO.Directory.Exists(fd))
            {
                System.IO.Directory.CreateDirectory(fd);
            }

            // Test 2
            // 將虛擬路徑映射到實際文件系統路徑
            string physicalPath = Server.MapPath(fd);

            // 檢查目錄是否存在
            if (!Directory.Exists(physicalPath))
            {
                // 創建目錄
                Directory.CreateDirectory(physicalPath);
            }
        }
    }
}

測試結果顯示,ChatGPT 方法可行。

********************************************************************************

【實際測試】雖然 Fortify SCA 可過關,但是程式實際執行,會出錯。

System.Web.HttpException: ''D:/Production2/TempImageFiles/' 是實體路徑,但必須使用虛擬路徑。'


User

執行失敗,System.Web.HttpException: ''C:/Production/TempImageFiles/' 是實體路徑,但必須使用虛擬路徑。'

ChatGPT

對不起,我誤解了您的情況。在 ASP.NET WebForms 中,Server.MapPath 方法將虛擬路徑映射到實際的伺服器文件系統路徑,但您遇到的錯誤是因為 Server.MapPath 方法只能用於將虛擬路徑映射到應用程式的虛擬目錄,而不能映射到任意的實體路徑。

如果您無法使用虛擬路徑,那麼您可能需要從另一個角度解決您的問題。這裡有幾種方法可以嘗試:

  • 使用絕對路徑並進行驗證:您可以直接使用絕對路徑,並在使用之前進行嚴格的驗證,以確保路徑是安全的。這可能涉及檢查路徑是否位於預期的目錄結構中,並且不包含任何惡意的路徑操作。
  • 使用配置文件設定:您可以在 Web.config 或 App.config 文件中定義路徑,然後在應用程式中使用這些設定。這樣做可以提供一個中央地點來管理您的路徑,同時還可以避免直接將路徑硬編碼到您的程式碼中。
  • 限制用戶輸入:如果可能,儘量限制用戶輸入的選項,以減少對路徑操作的潛在攻擊面。您可以使用下拉列表、勾選框或預定義的選項來控制用戶可以選擇的路徑。

請根據您的情況選擇最適合您需求的方法。如果您需要進一步的幫助,請告訴我們您的需求,我們將竭誠為您服務。

********************************************************************************

修改程式

Web.Config

<?xml version="1.0" encoding="utf-8"?>
<!--
  如需如何設定 ASP.NET 應用程式的詳細資訊,請前往
  https://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.8" />
    <httpRuntime targetFramework="4.8" />
  </system.web>
  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" />
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
    </compilers>
  </system.codedom>
  <appSettings>
    <add key="TempFolder" value="D:\Production\TempImageFiles\" />
    <add key="TempFolder2" value="\TempImageFiles2\" />
  </appSettings>
</configuration>

Default.aspx.cs

using System;
using System.Configuration;
using System.IO;

namespace WebApplication1
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // Test 1
            string fd = (string)ConfigurationManager.AppSettings["TempFolder"] + @"\";
            if (!System.IO.Directory.Exists(fd))
            {
                System.IO.Directory.CreateDirectory(fd);
            }

            // Test 2
            // 將虛擬路徑映射到實際文件系統路徑
            //string physicalPath = Server.MapPath(fd);
            string fd2 = (string)ConfigurationManager.AppSettings["TempFolder2"] + @"\";
            string physicalPath = Server.MapPath(fd2);

            // 檢查目錄是否存在
            if (!Directory.Exists(physicalPath))
            {
                // 創建目錄
                Directory.CreateDirectory(physicalPath);
            }
        }
    }
}


下圖,Deploy 到網站,執行,目錄建立成功。


再次掃描,Fortify SCA 過關。

********************************************************************************

結論:使用 Server.MapPath 搭配 虛擬路徑,可通過 Fortify SCA 的 Path Manipulation 檢查。

(完)

相關

沒有留言:

張貼留言