[研究]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()) { // 讀取資料 } // 資料讀取完成後,自動釋放相關資源 } |
********************************************************************************
(完)
相關
沒有留言:
張貼留言