PVS-Studio 是一套源碼檢測軟體(小知識:專業術語叫 SCA,(Static Code Analysis 靜態程式分析),知名度遠不及 Fortify、Checkmarx 或 SonarQube,不過,PVS-Studio 專注於 C、C#、C++、Java 四種語言,且有給學生及開源專案免費授權方案,好像也值得試看看。以下是我在 Linux 上安裝並掃瞄 .NET 專案的筆記。

官方的安裝及使用說明很清楚,下載及執行方式設計得蠻簡便,下面我這次主要參考的文件:

安裝設定摘要:(我的測試作業系統為 Ubuntu 22.04)

  1. 需先安裝 .NET 8 SDK
  2. PVS-Studio C# Analyzer 依賴 PVS-Studio C++ Analyzer (pvs-studio),但有包成 apt 套件會一併下載安裝,基本上可無腦完成
    執行以下指令新增 apt 套件來源及安裝
    wget -q -O - https://cdn.pvs-studio.com/etc/pubkey.txt | \
      sudo apt-key add -
    sudo wget -O /etc/apt/sources.list.d/viva64.list \
      https://cdn.pvs-studio.com/etc/viva64.list
    sudo apt-get update
    sudo apt-get install pvs-studio-dotnet    
    # 若看到版號代表安裝完成
    pvs-studio-dotnet --version
    
  3. 輸入授權序號啟用,授權資料會寫入 ~/.config/PVS-Studio/PVS-Studio.lic學生、教師開源專案開發者可免費使用:
    pvs-studio-analyzer credentials ${USER_NAME} ${LICENSE_KEY}
    # 學生、教師免費使用之序號設定方式,每個檔案開頭需加指定註解文字
    # https://pvs-studio.com/en/order/for-students/
    pvs-studio-analyzer credentials PVS-Studio Free FREE-FREE-FREE-FREE
    # 開源專案需填表申請,並在 README.md 加註 Credit 資訊
    # https://pvs-studio.com/en/order/open-source-license/
    
  4. OWASP 資安掃瞄是停用的,要編輯 ~/.config/PVS-Studio/Settings.xmlDisableOWASPAnalysisCs 選項設成 false:
    <?xml version="1.0" encoding="utf-8"?>
    <ApplicationSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">    
      <!-- ... -->
      <DisableOWASPAnalysisCs>false</DisableOWASPAnalysisCs>
      <!-- ... -->
    </ApplicationSettings>
    
  5. 與 SonarQube 相比,PVS-Studio 掃瞄 .NET 專案相對簡單,一行指令搞定,結果會寫成 JSON 或 XML:
    pvs-studio-dotnet -t vunerable-sample.sln -o result.json --progress
    

但實測 PSV-Studio 的偵測能力不如預期,參考官方文件案例,用以下程式片段測試 PVS-Studio 抓得出 SQL Injection:

using System.Data.SqlClient;

var db = new DBHelper();
db.ProcessUserInfo(args[0]);

public class DBHelper
{
    string _connectionString = "Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;";
    public void ProcessUserInfo(String userName)
    {
        var command = "SELECT * FROM Users WHERE userName = '" + userName + "'";
        ExecuteCommand(command);
    }

    private void ExecuteCommand(String rawCommand)
    {
        using (SqlConnection connection = new SqlConnection(_connectionString))
        {
            using (var sqlCommand = new SqlCommand(rawCommand, connection))
            {
                using (var reader = sqlCommand.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        // Process the data
                    }
                }
            }
        }
    }
}

但改成以下寫法就抓不到了:

using System.Data.SqlClient;

Test(args[0]);

void Test(string userName)
{
    var cnStr = "Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;";
    using (var cn = new SqlConnection(cnStr))
    {
        cn.Open();
        var cmd = new SqlCommand("SELECT * FROM Users WHERE userName = '" + userName + "'", cn);
        using (var reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                // Process the data
            }
        }
    }
}

為了對照,我寫了一個混合版,同時用 PVS-Studio 與 SonarQube 社群版掃瞄,比較結果。

PVS-Studio 只抓到 DbHelper.ProcessUserInfo() 的 SQL Injection (Line 31):

SonarQube 社群版抓到寫死密碼及 Test() 的 SQL Injection,但遺漏了 DbHelper.ProcessUserInfo():

順便再測了 Github Copilot,表現讓人驚豔,兩處 SQL Injection 跟寫死密碼都有被抓出來:

綜合以上的簡單體驗,PVS-Studio 安裝及批次掃瞄夠簡便,但在簡單 C# SQL Injection 漏洞程式碼測試表現比 SonarQube 社群版(CE)弱些(有可能 PVS-Studio 的強項是 C/C++),但意外有抓到 SonarQube CE 未檢測到的項目,個人覺得若要使用,整合作為 SonarQube 擴充套件,與 SonarQube 互補盲點是較好的做法。

Simple test of SAST tool - PVS-Studio.


Comments

Be the first to post a comment

Post a comment