# 產完 SBOM 之後就沒事了? 用 OSV 開源漏洞資料庫查到底哪些元件有風險
## 拿到 SBOM 之後?
如果只是產完 SBOM 就結束,那差不多就是去醫院健檢,拿到一疊報告後就收進櫃子,只是單純花時間精力,沒有真正獲得想要的結果 **安全**。
這篇要講的是拿到 SBOM 之後,怎麼從這一大堆文字中找出有風險的元件,並且安排下一步的更新計畫。
如果你是還不知道 SBOM 是什麼,或是不知道怎麼從你的軟體專案中產生SBOM,可以看我之前寫過的另一篇 [使用微軟開源工具 sbom-tool 自動產生 SBOM軟體物料清單](https://hackmd.io/@Not/MS_SBOM_tool) 先產出 SBOM,再回頭來看這篇。
## 使用 Google 的 OSV-Scanner 掃描漏洞
[OSV-Scanner](https://google.github.io/osv-scanner/) 是一個 Google 提供的自動掃描工具,可以自動檢查的 SBOM,是否和 [OSV database](https://osv.dev/) 這個開源漏洞資料庫內的紀錄相符,幫助開發人員更新有風險的元件。
可以在 **[OSV-Scanner官方網站下載 命令列執行工具(CLI)](https://github.com/google/osv-scanner/releases)** 進行掃描。
## 檢查有風險的套件
我這邊使用的方式是把使用微軟sbom tool產出來的 sbom 檔案 spdx.json 當作來源檔,用 **-S 檔名** 的參數,完整指令如下
```C:\Downloads> osv-scanner_1.3.2_windows_amd64.exe -S manifest.spdx.json```
---
## 產生結果
如果掃描沒有出現該修正的,只會顯示 ```No issues found```
範例如下
```
C:\SBOMTool> osv-scanner C:\SBOMTool\trivy.spdx.json
C:\SBOMTool\trivy.spdx.json file and found 47 packages
End status: 0 dirs visited, 1 inodes visited, 1 Extract calls, 5.3672ms elapsed, 5.3673ms wall time
No issues found
PS C:\SBOMTool>
```
---
如果是有發現異常,2024年開始預設結果會有附上 CVSS 分數
```
╭─────────────────────────────────────┬──────┬───────────┬─────────────────────────────────┬─────────┬──────────────────────────────────────╮ ≈
│ OSV URL │ CVSS │ ECOSYSTEM │ PACKAGE │ VERSION │ SOURCE │
├─────────────────────────────────────┼──────┼───────────┼─────────────────────────────────┼─────────┼─────────────────────────────────────┤ ≈
│ https://osv.dev/GHSA-mv2r-q4g5-j8q5 │ 7.5 │ NuGet │ Microsoft.Data.OData │ 5.7.0 │ E:\SBOM\spdx_2.2\manifest.spdx.json │
│ https://osv.dev/GHSA-9mvj-f7w8-pvh2 │ 6.4 │ NuGet │ bootstrap │ 3.4.1 │ E:\SBOM\spdx_2.2\manifest.spdx.json │
│ https://osv.dev/GHSA-25c8-p796-jg6r │ 8.1 │ NuGet │ Microsoft.AspNet.Identity.Owin │ 2.0.0 │ E:\SBOM\spdx_2.2\manifest.spdx.json │
╰─────────────────────────────────────┴──────┴───────────┴─────────────────────────────────┴─────────┴──────────────────────────────────────╯ ≈
```
* CVSS 分數是用來衡量漏洞嚴重的,分數範圍為 0 至 10,10 為最嚴重
* [](https://www.wallarm.com/what/what-is-cvss)
---
## 以下是舊版的產生結果,沒有分數
```
PS C:\MyDotnetProjectName專案名稱\SBOM> osv-scanner_1.3.2_windows_amd64.exe -S manifest.spdx.json
Scanned C:\MyDotnetProjectName專案名稱\SBOM\manifest.spdx.json as SPDX SBOM and found 140 packages
╭─────────────────────────────────────┬───────────┬──────────────────────────────────┬─────────┬────────────────────╮ ≈
│ OSV URL (ID IN BOLD) │ ECOSYSTEM │ PACKAGE │ VERSION │ SOURCE │ ≈
├─────────────────────────────────────┼───────────┼──────────────────────────────────┼─────────┼────────────────────┤ ≈
│ https://osv.dev/GHSA-g3q9-xf95-8hp5 │ NuGet │ NuGet.Protocol │ 5.11.0 │ manifest.spdx.json │ ≈
│ https://osv.dev/GHSA-qrmm-w75w-3wpx │ NuGet │ Swashbuckle.AspNetCore.SwaggerUI │ 6.3.0 │ manifest.spdx.json │ ≈
│ https://osv.dev/GHSA-jxwx-85vp-gvwm │ NuGet │ jQuery.Validation │ 1.11.1 │ manifest.spdx.json │ ≈
│ https://osv.dev/GHSA-8g2p-5pqh-5jmc │ NuGet │ System.Data.SqlClient │ 4.8.1 │ manifest.spdx.json │ ≈
│ https://osv.dev/GHSA-rxg9-xrhp-64gj │ NuGet │ System.Drawing.Common │ 5.0.0 │ manifest.spdx.json │ ≈
╰─────────────────────────────────────┴───────────┴──────────────────────────────────┴─────────┴────────────────────╯ ≈
```
可以看到有 OSV URL 代表使用到的套件在資料庫中有記錄,可以點擊網址,看看風險影響的程度以及要更新到哪一個版本才是安全的。
## OSV URL 的畫面
我以其中一個掃到的風險舉例,我上面掃描檢測後看到使用的 jQuery.Validation 是 1.11.1 版,對應的網址是 https://osv.dev/vulnerability/GHSA-jxwx-85vp-gvwm ,打開後看到有說明
The project contains one or more regular expressions that are vulnerable to ReDoS (Regular Expression Denial of Service)
專案包含一個或多個易受 ReDoS(正則表示式拒絕服務)攻擊的正則表達式
最下方則是說明要更新到哪個版本 Fixed 1.19.3。

## 更新套件要注意的事
直接更新套件這種粗暴的作法通常很可能發生問題,建議還是去看一下官方網站是否有要注意的事,或是跨版號有沒有哪些功能不能使用。
剛好 jQuery Validation 我只有 2個網頁有使用到,可以事先評估更新後到時候要檢查的範圍不算太大。
我使用的是 Visual Studio 的 nuget 套件,因此更新也從這個方式更新,可以看到我在搜尋已安裝套件時, nuget 也幫我做了有漏洞的黃色驚嘆號標示,提醒我需要更新了。

更新很簡單,就用下拉選單拉到 1.19.3 以上,既然要升級就直接拉到最新版的 1.19.5

更新後,在操作畫面上檢查功能是否正常,這樣這一條就修復完畢了。
## 能不能更新或是不修風險? 可以,但要做風險評估
這個 jQuery Validation 的風險是 ReDowS (Regular Expression Denial of Service),他是什麼呢?
這是當使用者輸入正規表達式 (Regex)給伺服器做檢測時,可能會增加伺服器負擔,花費更多時間處理驗證,藉以消耗伺服器資源的攻擊。更多完整訊息可以參考微軟的 [安全性簡報 規則運算式拒絕服務攻擊與防禦](https://learn.microsoft.com/zh-tw/archive/msdn-magazine/2010/may/security-briefs-regular-expression-denial-of-service-attacks-and-defenses)
可以看到攻擊類型是針對伺服器,換言之,如果你能確保你傳給的後端驗證程式碼**沒有使用到 regex 驗證**,那這個風險就真的只是風險,並不會造成立即性的威脅。
如果是很老舊的專案已經不再進行變更了,這也是一個修補方式,但要記得留下說明文件,提醒後面想要接手修改的人有這個風險,不要某天加入了 regex 驗證到後端,到時候就出事了。
## 從後端更新進行下手
在 Net Framework 4.5 之後,Regex 建構式中加入了一個選用的 TimeSpan 參數, 讓開發者可以自行決定 timeout 時間,例如把秒數設定為很短例如2秒,也可以防止攻擊。但必須要針對每個 regex 驗證的地方進行設定
說明與範例如下
* Regex(String, RegexOptions, TimeSpan)
針對指定的規則運算式,使用修改模式的選項,以及指定在逾時前模式比對方法應該嘗試比對的時間長度的值,初始化 Regex 類別的新執行個體。
```
Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase, TimeSpan.FromSeconds(2));
```
如果前端程式碼使用的範圍非常大,但都是統一呼叫後端固定的一個位置,也可以選擇更新後端的部分,避開前端一大堆頁面,加快修補的速度。
## 結論
自此,我們有了至少 3 種方式進行修補,分別為
1. 更新直接受到影響的前端元件,並檢查是否可以正常運作
優點:掃描不會再跳這個風險有問題
缺點:有使用到的前端畫面要去檢查
2. 確認風險影響範圍,做好風險評估,了解這個風險不會造成立即威脅並留下文件紀,防止後人誤觸。
優點:不須異動程式碼
缺點:要去檢視程式碼,評估這個攻擊是否能夠利用(得會攻擊手法)
3. 從風險攻擊目標的後端程式下手,切斷可能的攻擊手法。
優點:不須更新直接元件
缺點:需要改動後端程式程式碼
這3種方法都是因應風險做出的處理方式,並不一定只有更新才能夠防範,挑選最適合的方式即可。
---
## 參考來源
* Google 釋出 漏洞掃描工具:OSV-Scanner
https://blog.longwin.com.tw/2023/01/google-release-vulnerability-code-scan-osv-scanner-2023/
* [Regex] 值得注意的 Regular Expression 樣式的潛在風險
http://aspnet2share.blogspot.com/2010/09/regex-potential-risks.html
* [Regex] .Net 4.5 中新增的 Regex 建構式參數
http://aspnet2share.blogspot.com/2014/07/regex-timeout-parameter.html
* Regex 建構函式
https://learn.microsoft.com/zh-tw/dotnet/api/system.text.regularexpressions.regex.-ctor?redirectedfrom=MSDN&view=net-7.0#System_Text_RegularExpressions_Regex__ctor_System_String_System_Text_RegularExpressions_RegexOptions_System_TimeSpan_
* [技術分享] ReDoS
https://cyrilwang.pixnet.net/blog/post/32357037
###### tags: `資安`