2024年3月5日 星期二

[研究]ASP.NET, Fortify SCA 報告 "無法釋出由 ExecuteReader() 所配置的系統資源"

[研究]ASP.NET, Fortify SCA 報告 "無法釋出由 ExecuteReader() 所配置的系統資源"

2024-03-05

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

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

【Fortify SCA報告】的 Details 說明

Abstract:

WebForm1.aspx.cs 中的 Button_Export_Click() 函數有時會無法釋出由第 290 行的 ExecuteReader() 所配置的系統資源。

Explanation:

程式可能會無法釋出系統資源。

資源洩漏至少有兩種常見原因:

- 錯誤條件以及其他異常情況。

- 不確定程式的哪一部份負責釋放資源。

在此案例中,程式不會釋放 WebForm1.aspx.cs  中第 290 行配置的資源,但執行此操作的程式路徑會存在。

大部分的 Unreleased Resource 問題都會導致一般軟體可靠性問題,但是如果攻擊者蓄意觸發資源洩漏的話,攻擊者就可能會藉由耗盡資源集區的方式來發動 Denial of Service 攻擊。

範例:在正常情況下,以下程式碼會執行資料庫查詢,處理資料庫傳回的結果,然後關閉分配的 SqlConnection 物件。但是,如果在執行 SQL 或處理結果時發生異常,SqlConnection 物件將不會關閉。如果這種情況時常發生的話,那麼資料庫將會用盡可用指標,並且無法再執行任何 SQL 查詢。

        ...

        SqlConnection conn = new SqlConnection(connString);

        SqlCommand cmd = new SqlCommand(queryString);

        cmd.Connection = conn;

        conn.Open();

        SqlDataReader rdr = cmd.ExecuteReader();

        HarvestResults(rdr);

        conn.Connection.Close();

        ...

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

【Fortify SCA報告】的 Recommands 說明

Recommendations:

絕不依賴 Finalize() 來回收資源。若要叫用物件的 Finalize() 方法,記憶體回收器必須判定物件是否可以用於記憶體回收。因為垃圾收集器只有在 VM 記憶體過低時才會執行。因此不確定會在何種緊急情況下呼叫 Finalize() 方法,即使曾經呼叫此方法 (程式語言不保證是否會呼叫)。當最後執行記憶體回收器時,會在短時間內回收大量資源,這會造成效能驟增並降低整體系統輸送量。當系統負載增加時,便可以明顯地感受到此影響。

可以使用 C# 關鍵字 'using' (使用 IDisposable 介面執行清除),而不是明確關閉管理資源的物件。以下的兩段程式碼可達到相同的結果:

以下程式碼使用 finally 關鍵字:

SqlConnection conn;
try {
  conn = new SqlConnection(connString);
  doWork(conn);
} finally {
  if (conn != null) {
    conn.Close();
  }
}

以下程式碼使用 using 關鍵字:

using (SqlConnection conn = new SqlConnection(connString)) {
  doWork(conn);
}

敝人是使用 using (SqlConnection conn = new SqlConnection(connString)),但報告說 SqlDataReader reader = command.ExecuteReader(); 有問題,Recommands 有點雞同鴨講,所以報告的建議並不可行。

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

【ChatGPT】

這個問題通常發生在未正確釋放 ExecuteReader() 返回的資源,進而導致系統資源無法正確釋放。解決這個問題的方法之一是確保在使用完 ExecuteReader() 後,使用 Dispose() 方法或者 using 關鍵字來釋放相關的資源。這可以通過下面的方式來實現:

using (var reader = command.ExecuteReader())
{
    while (reader.Read())
    {
        // 讀取資料
    }
    // 資料讀取完成後,自動釋放相關資源
}


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

(完)

相關

沒有留言:

張貼留言