2024年4月8日 星期一

[研究]ASP.NET, WebForm, 程式 string csvline = csvFile.ReadLine(); 被 Fortify SCA 判定 Denial of Service (Low)

[研究]ASP.NET, WebForm, 程式 string csvline = csvFile.ReadLine(); 被 Fortify SCA 判定 Denial of Service (Low)

2024-04-07

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

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

ASP.NET, WebForm, 下面程式,其中 string csvline = csvFile.ReadLine(); 被 Fortify SCA 判定 Denial of Service,如何修改

Default.aspx.cs

using (var csvFile = new StreamReader(File.OpenRead(openFilename)))
{
    while (!csvFile.EndOfStream)
    {
        string csvline = csvFile.ReadLine();                  
    }
}

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

【Fortify SCA】Recommands

驗證使用者輸入以確保它不會造成資源利用不當。

範例 3:以下程式碼允許使用者指定執行緒進入休眠的時間長短 (正如 Example 1 所示),但是只有值是在合理的範圍內時才可行。

  int usrSleepTime = Int32.Parse(usrInput);
  if (usrSleepTime >= SLEEP_MIN && usrSleepTime <= SLEEP_MAX) {
    Thread.Sleep(usrSleepTime);
  } else {
    throw new Exception("Invalid sleep duration");
  }
}

範例 4:以下程式碼會從 zip 檔案中讀取字串 (正如 Example 2 所示),但是其可讀取的最大字串長度為 MAX_STR_LEN 個字元。

   using (StreamReader sr = new StreamReader("file.zip"))   {
    int intC;
    while ((intC = sr.Read()) != -1) {
    char c = (char) intC;
    StringBuilder sb = new StringBuilder();
    if (c == '\n') {
      break;
    }
    if (sb.length() >= MAX_STR_LEN) {
      throw new Exception("input too long");
    }
    sb.Append(c);
  }
  string line = sb.ToString();

範例 5:以下程式碼停用了要求大小限制,允許使用不受限的要求承載大小。這可能會導致與不受控制的資源消耗有關的安全問題,特別是如果正在緩衝要求主體時,會增加 DoS 攻擊的可能性。 

    [DisableRequestSizeLimit]
    [HttpPost]
    public async Task <string> Index()
    {
        using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
        {
            
            char[] buffer = new char[40];

            reader.Read(buffer);
            ...
        }
    }

建議您使用 [RequestSizeLimit(...)] 變更預設限制,或將要求大小設定為所需的值。

Tips:

1. 即使攻擊者無法 (至少無法直接) 控制要消耗的系統資源使用量,或是持續使用系統資源的時間,仍無法避免 Denial of Service 的發生。相反地,程式設計師可能會選擇不安全的常數值來指定這些參數。Fortify Secure Coding Rulepacks 會將這種情況報告為潛在的 Denial of Services 弱點。

2. 針對此弱點的建議修正可能無法偵測,所以您可能需要在進行補救之後執行額外的稽核以確認修正問題。在確認弱點已移除後,可以安全地抑制該問題。

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

ChatGPT

Fortify SCA 的 Denial of Service(DoS)檢測可能會因為未經適當驗證或限制地讀取大型文件而導致潛在的資源耗盡問題。為了解決這個問題,您可以添加一些檢查來限制正在處理的輸入文件的大小。以下是修改您的程式碼的方法:

Default.aspx.cs

using (var csvFile = new StreamReader(File.OpenRead(openFilename)))
{
    long maxFileSize = 100 * 1024 * 1024; // 最大允許的文件大小(在這個例子中為100 MB)
    long totalBytesRead = 0;

    while (!csvFile.EndOfStream && totalBytesRead < maxFileSize)
    {
        string csvline = csvFile.ReadLine();
        totalBytesRead += System.Text.Encoding.Unicode.GetByteCount(csvline); // 假設使用 Unicode 編碼
        // 在這裡處理 csvline
    }

    if (totalBytesRead >= maxFileSize)
    {
        // 處理文件超過最大允許大小的情況
    }
}

在這個修改後的版本中:

我引入了一個 maxFileSize 變數來定義輸入文件的最大允許大小。您可以根據您的具體需求調整此值。

在循環內部,我添加了一個檢查,以確保從文件讀取的總字節數(totalBytesRead)不超過最大允許大小(maxFileSize)。

我使用 System.Text.Encoding.Unicode.GetByteCount(csvline) 來估算每行讀取的字節數。根據您的文件的實際編碼進行調整。

如果文件超過最大允許大小,您可以適當地處理此情況。

通過添加這些檢查,您可以防止代碼讀取過大的文件,從而減少因資源耗盡而導致的DoS攻擊的風險。根據您的應用程序的可接受大小限制調整 maxFileSize 值。

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

Copilot

Fortify SCA 可能會將 csvFile.ReadLine() 視為 Denial of Service (DoS) 攻擊的風險,因為如果 CSV 文件非常大,這個操作可能會消耗大量的記憶體和 CPU 資源。

一種可能的解決方案是限制讀取的行數。例如,您可以設定一個最大行數,並在達到該數量時停止讀取。以下是一個範例:

int maxLines = 10000; // 設定最大行數
int lineCount = 0;

using (var csvFile = new StreamReader(File.OpenRead(openFilename)))
{
    while (!csvFile.EndOfStream && lineCount < maxLines)
    {
        string csvline = csvFile.ReadLine();
        lineCount++;
    }
}

這樣,如果文件的行數超過 maxLines,則不會讀取所有行,從而降低了 DoS 攻擊的風險。請注意,這可能不適合所有情況,因為這可能會導致數據丟失。您需要根據您的具體需求來調整這個解決方案。如果您的應用程序需要處理大型文件,則可能需要考慮使用更高效的數據處理方法,例如分批處理或流處理。

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

實際測試,ChatGPT 和 Copilot的方法,Foritfy SCA都仍報告有問題,都在 string csvline = csvFile.ReadLine(); 這行。

(待續)

相關

沒有留言:

張貼留言