在資訊越來越發達的情況下,資安也更備受重視,做資安掃描的要求也不少見。
其實看了滿久的資料,網路上詢問解法的文章不少,然取決於架構與情境,解法也五花八門。
因此這裡就只約略簡單的介紹,以及此次解決的方法。
以下先放一段發生 Unreleased Resource 的範例程式
Stream iStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
return File(iStream, "application / Excel", fileName);
報告內容
以下內容取自 Fortify 網站,檢測後收到的報告內容也是相同的。
Kingdom : Code Quality
摘要
無法釋放由 FileStream() 分配的系統資源。
後來好像有更新,現官網顯示為 :「該程式可能無法釋放系統資源。」
解釋
該程序可能無法釋放系統資源。資源洩漏至少有兩個常見原因:
- 錯誤條件和其他異常情況。
- 不清楚程序的哪一部分負責釋放資源。
大多數的 Unreleased Resource 會導致一般軟體可靠性問題。 但如果攻擊者故意觸發資源洩漏,則攻擊者可能會藉由耗盡資源集區來發起 Denial of Service ( 拒絕服務 ) 攻擊。
示例
下列範例不會關閉所開啟的檔案控制。在 StreamReader 的 Finalize() 方法最終會呼叫 Close(),但不確定何時會呼叫 Finalize() 方法。
事實上,無法保證會呼叫 Finalize()。在忙碌的環境,可能會導致虛擬機耗盡所有能使用的檔案控制。
private void processFile(string fName)
{
StreamWriter sw = new StreamWriter(fName);
string line;
while ((line = sr.ReadLine()) != null)
processLine(line);
}
Solution
看到不少情境都是發生在 Java 沒有關閉 getInputStream() 或 getOutputStream()
大多提供解法都是採用以下處理搭配 Try Finally ,或是直接在問題行加上Dispose Method。
if (writer != null) {
writer.close();
}
只是記得在某處看過,此議題不推薦顯式關閉處理。
且在 ASP.NET MVC 的執行生命週期使用 FileStreamResult 時也無法使用 using 陳述式,否則會發生錯誤 : 「無法存取關閉的檔案」。
在 FileStreamResult 裡的 WriteFile 方法會使用 using ,待寫入 Response.OutputStream 之後自動清除記憶體空間釋放檔案。
根據以上情境,應該是 Fortify 誤判了。
顯式關閉 ( Explicitly closing )
整個開發過程中,系統資源可依是否由 CLR 管理分配和釋放,分為 託管 及 非託管。
非托管資源,或者需要顯式釋放的託管資源,需要繼承 IDisposable 介面以實現 Dispose 模式,告知此類型需要調用Dispose方法釋放資源。
呼叫 Dispose() 或 Close() 以釋放資源的動作,即是 顯式關閉。
補充
C# 以 using 關鍵字做自動管理資源, Java 為 Try-with-resources。
手動關閉都是 close method。
以 Java 的例子,即使使用 Try-with-resources 也是可能被標記 Unrelease Resource : Stream。
最終還是回歸土法煉鋼,使用單純的 Try-With-Resources 並在其區域內宣告使用資源,並在 Finally 區塊判斷若非 null ,以 Close method 釋放。
結語
網路上的解法有很多,應該可以繞過 Fortify 的機制,但本是為了資安所做的掃瞄好像就失去了原本的意義。
因此不太想採用顯式關閉的處理,還好在與老闆報告說明後便直接註銷了此議題,可要檢查的項目也還是堆積如山呢...
而看了那麼多案例與文章,仍是不知為不知
還須努力
( 主要還好先前就有看過保哥的文章,解釋得非常清楚。因此看到報告時才能立即反應過來,否則大概如墮五里霧中 )
參考資料
- ASP.NET MVC 開發心得分享 (19):Action 要小心使用 using
- https://blog.csdn.net/wypdao/article/details/8633773
- https://stackoverflow.com/questions/42270898/fortify-security-issue-unreleased-resource-stream
- https://blog.miniasp.com/post/2010/08/14/ASPNET-MVC-Developer-Note-Part-19-The-using-in-Action-method
- https://vulncat.fortify.com/zh-tw/detail?category=Unreleased%20Resource&subcategory=Streams#C%23%2FVB.NET%2FASP.NET
- https://stackoverflow.com/questions/56289611/fortify-security-issue-unreleased-resource-stream-for-try-with-resource
- https://blog.csdn.net/wypdao/article/details/8633773
- https://blog.csdn.net/chdyiboke/article/details/65937091
- https://stackoverflow.com/questions/67475344/fortify-unreleased-resource-streams-issue-for-having-a-ternary-in-try-with-res
- https://stackoverflow.com/questions/73454556/fortify-unreleased-resource-streams-try-with-resource-in-loop
- https://stackoverflow.com/questions/42270898/fortify-security-issue-unreleased-resource-stream
- https://dotblogs.com.tw/stanley14/2018/07/08/Fortify_UnreleasedResource_Streams
- https://www.cnblogs.com/luminji/archive/2011/01/05/1926468.html
- https://www.cnblogs.com/luminji/archive/2011/03/29/1997812.html
- https://medium.com/%E7%A8%8B%E5%BC%8F%E8%A3%A1%E6%9C%89%E8%9F%B2/fortify-unreleased-resource-streams-%E8%A7%A3%E6%B1%BA%E6%96%B9%E5%BC%8F-862dbadf017a