SAST 掃描
依賴審計涵蓋您導入的程式碼;SAST 則涵蓋您撰寫的程式碼。它透過模式匹配(並且,在污點模式下,會追蹤資料流)來找出經典缺陷:命令/SQL 注入、路徑遍歷、不安全的反序列化、對未受信任輸入執行 eval/動態執行、硬編碼的加密金鑰、缺少身分驗證檢查。高誤報率是其固有特性——正確做法是透過可達性分類,而非直接忽略所有警報。
何時執行
- 在發布之前,針對差異內容或整個專案樹。
- 當您新增處理未受信任輸入的程式碼時(一個新工具、端點、解析器或 shell 呼叫)。
- 在 CI 中,針對 PR 執行(以差異為範圍,速度快且只標記新問題)。
執行掃描
# semgrep —— 安全規則集。`auto` 會根據偵測到的語言自動選擇規則。
semgrep scan --config auto --error .
# 聚焦、訊號更強的規則集(比 auto 更少雜訊):
semgrep scan --config p/security-audit --config p/secrets --config p/command-injection .
# 僅掃描差異(CI 中對 PR 使用 —— 快速,僅顯示新發現):
semgrep scan --config auto --baseline-commit origin/main .
對於更深入的資料流分析(未受信任的輸入是否真的到達了危險的接收點?),CodeQL 更強大但也更重量級:
codeql database create db --language=javascript # 或 rust, python, …
codeql database analyze db --format=sarif-latest --output=results.sarif \
codeql/javascript-queries:codeql-suites/javascript-security-extended.qls
分類處理 —— 追蹤源頭,而非直接關閉
對於每個發現,請追蹤來源 → 接收點的路徑:
- 輸入是否可控? 對硬編碼常數執行
child_process.exec沒問題;但如果對請求參數執行,就是命令注入漏洞。semgrep 標記的是接收點;您需要確認來源。 - 它們之間是否有消毒機制? 如果在到達接收點之前,該值已經過驗證/跳脫(例如 zod 模式、允許清單、參數化查詢),則為誤報 —— 請用
# nosemgrep: <規則ID>標記它,並附上一行原因說明,而不是直接忽略。 - 是真的漏洞嗎? 在源頭(驗證/跳脫輸入)或接收點(參數化、使用安全 API)進行修復,而不是壓制警告。
切勿為了清除所有警報而盲目禁用規則 —— 這樣做會把雜訊中唯一真實的漏洞一起壓制。請逐行抑制,並附上理由。
實際應優先修復的項目(按價值排序)
- 注入(命令/SQL/模板)存在於任何用戶可訪問的路徑上 —— 這是最高嚴重性、最常被利用的漏洞類別。
- 路徑遍歷 —— 未經驗證的路徑到達檔案讀取/寫入操作(一個會寫入檔案的代理正是此類風險;應根據作用域檢查來設閘)。
- 對動態字串進行不安全的 exec/eval。
- 在安全上下文中使用硬編碼加密 / 弱隨機數。
邊界
SAST 僅靜態地查看單一儲存庫的原始碼 —— 它無法看到執行時期設定、由環境驅動的程式碼路徑,或僅在跨越服務邊界時才出現的缺陷。它補充、但從不取代真正的威脅模型和 [[dependency-audit]]。對於代理/工具執行時期而言,最強的控制措施通常是架構性的(一個對每個動作進行閘控的核心),而非逐行檢查 —— SAST 驗證的是該邊界周圍的程式碼。將它納入 [[security-preflight]]。