# C# 程式白箱檢測原始碼掃描工具介紹 Security Code Scan
## 起因
每次做程式碼掃描,都是等到功能全部寫完了,開發人員才把"整包"程式全部丟去掃描檢測。
如果其中一個地方用錯,就變成整份程式一大堆有類似問題全部都得修正。
而且寫了一堆程式,也不一定知道怎麼修正才是正確的,還要一直拜託掃描人員反覆幫忙檢測,測完也只收到了 "很多風險喔" ,最後還是不知道怎麼改。
如果能在第一個錯誤發生的時候就知道問題,而且當下立刻修正的話,未來就不會再發生。
為了達成這個目的,最好的時機點就是開發人員在寫程式碼的時候,當每寫一行或是每 save 一次,就能夠透過某種機制會自動檢查程式有沒有資安問題。
## Microsoft Security Code Analysis(MSCA)
因為我是寫微軟C#為主,所以先找上了官方文件的 Microsoft 安全性 Code Analysis
https://docs.microsoft.com/zh-tw/azure/security/develop/security-code-analysis-overview
但這一套是跟 Azure DevOps 綁在一起的付費功能
開始使用 Microsoft 安全性Code Analysis的必要條件,符合資格的Microsoft 統一支援供應專案,如下一節所述。
* Azure DevOps 組織。
* 安裝Azure DevOps組織擴充功能的許可權。
* 可同步處理至雲端裝載Azure DevOps管線的原始程式碼。
因為只想自己弄玩具起來玩,不想花錢,先列入考慮,再去找找免費方案
## OWASP Source Code Analysis Tools
循著微軟建議的解決方向,找到了 OWASP網頁中列出的原始碼分析工具
https://owasp.org/www-community/Source_Code_Analysis_Tools
OWASP有在網頁中強調 "我們不為特定軟體宣稱效用,只是整理選擇分析工具的標準和列出常見分析工具而已"
這邊擷取前半段作範例,裡面商業 開源 免費軟體都有,底下的參考文件也有列上包含整理自 nist 的掃描工具
![](https://i.imgur.com/80csokj.png)
## Security Code Scan
依照 OWASP 的列表,找到其中一個 [Security Code Scan](https://security-code-scan.github.io/) ,前身叫做 .NET Security Guard,更早以前則是 Roslyn Security Guard ,是可以掃C#程式碼的
安裝上可以選
1. 跟 Visual Studio 整合
2. 用 nuget 包跟程式專案整合
3. 獨立安裝成指令列介面
---
## 安裝方式1 跟 Visual Studio 整合
我先選了跟Visual Studio 整合 (2019以上才能用)
可以連到 [VisualStudio市集的官方下載點](https://marketplace.visualstudio.com/items?itemName=JaroslavLobacevski.SecurityCodeScanVS2019) 下載後執行
也可以在 Visual Studio 內安裝,以 Visual Studio 2022 的介面為例,選延伸模組 (X) > 管理延伸模組(M)
在跳出來的視窗左側選到**線上**後,在右上角的搜尋視窗輸入 SecurityCodeScan
![](https://i.imgur.com/wP2PLCD.png)
## 如何使用?
用上述方法安裝後,只要開啟程式專案,檢視其中一段程式碼,就會自動掃描
例如這張圖的例子,可以看到因為沒有加上CSRF防護,所以底下跳出了提醒 SCS0016
![](https://i.imgur.com/iRqVUIi.png)
## 如何修復?
在 Visual Studio 安裝並且執行的話,可以直接點擊 [SCS0016](https://security-code-scan.github.io/#SCS0016) 的連結後,會描述風險原因以及修正方式
以這邊來說,就是在 View 上增加 @Html.AntiForgeryToken() ,並在 Controller 前面加上 [ValidateAntiForgeryToken] 即可
![](https://i.imgur.com/2SikPg3.png)
---
## 安裝方式2 用 nuget 包跟程式專案整合
這個方法我自己沒有很喜歡,我期望的是開發環境的整合,所以這個就沒實作了
---
## 安裝方式3 獨立安裝
開啟 cmd 或 powershell 後,貼上來自 [security-scan 官方nuget]的訊息(https://www.nuget.org/packages/security-scan/)
這邊用的是
``` dotnet tool install --global security-scan --version 5.6.2 ```
輸入後執行情形如下,可以看到成功安裝的訊息
![](https://i.imgur.com/Bi7nFin.png)
順便一提, global 全域安裝 的安裝路徑會在這個位置
| OS | Path |
| -------- | -------- |
| Linux/macOS | $HOME/.dotnet/tools |
| Windows | %USERPROFILE%\.dotnet\tools |
* 資料來源 [dotnet tool install 命令](https://learn.microsoft.com/zh-tw/dotnet/core/tools/dotnet-tool-install)
---
## 設定PATH 環境變數
安裝後可能會有下面這個訊息,可以複製 setx PATH 那一行照著輸入就好
```
工具目錄 'C:\Users\UserName\.dotnet\tools' 目前不在 PATH 環境變數上。
您可執行下列命令將目錄新增至 PATH:
setx PATH "%PATH%;C:\Users\UserName\.dotnet\tools"
您可以使用下列命令來叫用工具: security-scan
已成功安裝工具 'security-scan' ('5.6.7' 版)。
```
---
## 獨立執行掃描與產生報告
因為是 global 全域安裝,之後就可以直接在 cmd 輸入 security-scan.exe 看看說明文件
```
PS C:\Windows\System32\WindowsPowerShell\v1.0> security-scan.exe
╔═╗┌─┐┌─┐┬ ┬┬─┐┬┌┬┐┬ ┬ ╔═╗┌─┐┌┬┐┌─┐ ╔═╗┌─┐┌─┐┌┐┌
╚═╗├┤ │ │ │├┬┘│ │ └┬┘ ║ │ │ ││├┤ ╚═╗│ ├─┤│││
╚═╝└─┘└─┘└─┘┴└─┴ ┴ ┴ ╚═╝└─┘─┴┘└─┘ ╚═╝└─┘┴ ┴┘└┘
.NET tool by Jaroslav Lobačevski v5.6.2
Usage:
-w, --excl-warn=VALUE (Optional) semicolon delimited list of warnings to
exclude
--incl-warn=VALUE (Optional) semicolon delimited list of warnings to
include
-p, --excl-proj=VALUE (Optional) semicolon delimited list of glob
project patterns to exclude
--incl-proj=VALUE (Optional) semicolon delimited list of glob
project patterns to include
-x, --export=VALUE (Optional) SARIF file path
-c, --config=VALUE (Optional) path to additional configuration file
--cwe (Optional) show CWE IDs
-t, --threads=VALUE (Optional) run analysis in parallel (experimental)
-n, --no-banner (Optional) don't show the banner
-v, --verbose (Optional) more diagnostic messages
--ignore-msbuild-errors
(Optional) Don't stop on MSBuild errors
-h, -?, --help show this message and exit
Example:
security-scan my.sln --excl-proj=**/*Test*/** --export=out.sarif --excl-warn=SCS1234;SCS2345 --config=setting.yml
```
---
## dot Net Framework 4.x 的專案,請裝另外一版離線安裝檔案
第一次試著跑了一次以後,看到錯誤訊息如下
![](https://i.imgur.com/bevSPsB.png)
會出現 Msbuild 失敗是因為我的專案是 dotnet framework 4.8的版本,官方說明有提到如果是 dotnet framework 4.x 的版本,請在 github 下載這個檔案再掃描 [security-scan4x.zip](https://github.com/security-code-scan/security-code-scan/releases)
另外我也有在找到 security-code-scan [github 其中一個 issue](https://github.com/security-code-scan/security-code-scan/issues/202),發問的人說他的硬碟有這個檔案,認為可能是 bug,底下回應建議他 ignore-msbuild-errors 。但我的情況跟這個無關。
## 成功掃描後的樣子
順利掃描的話,畫面就像這樣子
```=script
PS C:\my> security-scan my.sln
╔═╗┌─┐┌─┐┬ ┬┬─┐┬┌┬┐┬ ┬ ╔═╗┌─┐┌┬┐┌─┐ ╔═╗┌─┐┌─┐┌┐┌
╚═╗├┤ │ │ │├┬┘│ │ └┬┘ ║ │ │ ││├┤ ╚═╗│ ├─┤│││
╚═╝└─┘└─┘└─┘┴└─┴ ┴ ┴ ╚═╝└─┘─┴┘└─┘ ╚═╝└─┘┴ ┴┘└┘
.NET tool by Jaroslav Lobačevski v5.6.2
Loading solution 'my.sln'
Resolve 0:08.4521235 my.csproj (net6.0)
Finished loading solution 'my.sln'
Found: C:\my\my\Controllers\HomeController.cs(97,23): warning SCS0016: Controller method is potentially vulnerable to Cross Site Request Forgery (CSRF).
Found: C:\my\my\Web.config(25,1): warning SCS0023: View state is not encrypted.
Found: C:\my\my\Views\Web.config(36,1): warning SCS0023: View state is not encrypted.
Completed in 00:00:16
3 warnings
```
## 修復
以上面的掃描報告為例,有 3 個warnings
Found: HomeController.cs(97,23): warning SCS0016:
Found: Web.config(25,1): warning SCS0023:
Found: Views\Web.config(36,1): warning SCS0023:
但實際上只有 2種類型 SCS0016 和 SCS0023
可以用關鍵字去找對應的修復方式,在官方網站 [Security Code Scan](https://security-code-scan.github.io/) 也可以看到修復方式
以 SCS0016 為例,會在 Solution 的地方看到
view 要增加
```@Html.AntiForgeryToken()```
controller 要增加
```=C#
public class TestController
{
[HttpPost]
[ValidateAntiForgeryToken] //加這個
public ActionResult ControllerMethod(string input)
{
//Do an action in the context of the logged in user
}
}
```
![](https://i.imgur.com/V5EnvkJ.png)
---
## 安裝方法 1 和 3 要選哪個好?
小朋友才做選擇,大人當然是我全都要!
![](https://i.imgur.com/o8wlBbh.png)
* 在 Visual Studio 上的整合,寫程式的同時立刻就可以得知哪一段有問題,可以及早修復。
* 獨立安裝的方式,可以不開啟 Visual Studio 但是針對全程式碼掃描,方便產生全盤檢視的報告。
兩種方式各有優缺,因此兩種都推薦裝起來,掃就對了!
###### tags: `資安`