Loading...
2025-11-24 14:51
620

Semgrep 是一套輕量、可本機執行、社群規則豐富的 SAST(Static Application Security Testing)工具。它以「像寫程式一樣寫規則」為核心,學習成本低,十分適合快速導入與 CI/CD 落地。本教學會帶你完成 本機安裝 → 掃描 → 規則客製 → 忽略與白名單 → CI 整合,最後再與 CodeQL、SonarQube、Snyk Code、GitLab SAST、ESLint/型別檢查 等工具做系統性比較。

一、Semgrep 是什麼?為什麼用它

  • 跨語言:支援 JS/TS、Python、PHP、Go、Java、C/C++、Ruby、Kotlin、IaC(Terraform、Dockerfile)等。
  • 易擴充:規則語法接近程式碼,能寫「形狀比對(AST pattern)」與「資料流/污點分析(taint)」。
  • 速度快、可離線:本機秒級掃描,方便開發者日常自檢。
  • 生態健全:官方/社群規則庫豐富、可直接選用。

官方資源:Semgrep 官網DocsRegistry(規則庫)

二、安裝與第一次掃描(本機)

  1. 安裝(擇一):
    • macOS:brew install semgrep
    • pip:pip install semgrep
    • Docker:docker run --rm -v "$PWD:/src" semgrep/semgrep semgrep ci
  2. 快速掃描(自動選規則):
    semgrep scan --autofix --error

    --error:有命中時退出碼非 0,利於 CI 失敗;--autofix:支援規則指定的自動修復。

  3. 指定規則套件(例如 OWASP Top 10):
    semgrep scan --config p/owasp-top-ten

三、常用排除與最佳化(.semgrepignore)

在專案根目錄新增 .semgrepignore,排除第三方/編譯產物,降低雜訊與加速掃描:

# 典型前後端專案 node_modules/ vendor/ dist/ build/ coverage/ public/ *.min.js 

另外可用參數排除:--exclude node_modules --exclude vendor

四、寫一條自己的規則(從 0 到 1)

Semgrep 規則用 YAML 撰寫,可做語法模式比對與資料流分析。以下示範 PHP 中危險的 eval() 使用(僅示意):

rules: - id: php-avoid-eval severity: ERROR languages: [php] message: "避免使用 eval(),請改用安全的解析/執行方式" patterns: - pattern: eval(...) metadata: cwe: "CWE-95" owasp: "A03: Injection" 

將上面存成 .semgrep/php-security.yml,執行:

semgrep scan --config .semgrep/php-security.yml

五、污點(Taint)分析:找出「來源 → 匯點」的風險

當「不可信輸入」被傳遞到「危險函式(sink)」時,就可能造成注入。以 PHP 為例(簡化示意):

rules: - id: php-taint-sql severity: ERROR languages: [php] message: "外部輸入流入 SQL,請使用參數化查詢" mode: taint pattern-sources: - pattern: $_GET[...] - pattern: $_POST[...] pattern-sinks: - pattern: mysqli_query($conn, $QUERY) pattern-propagators: - pattern: $X = $Y 

六、抑制與基準線(Baseline)

  • 單點忽略:於程式碼加註解(依規則 id):
    // semgrep-ignore: php-avoid-eval -- 第三方相容性限制,已外層防護
  • 基準線:先在既有專案建立「當前允許狀態」,日後只攔截新警報:
    semgrep scan --baseline-commit  --config p/owasp-top-ten

七、在 CI/CD 中自動化(GitHub Actions 範例)

name: semgrep on: [push, pull_request] jobs: scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: returntocorp/semgrep-action@v1 with: config: p/owasp-top-ten generateSarif: true - name: Upload SARIF to GitHub Security uses: github/codeql-action/upload-sarif@v3 with: sarif_file: semgrep.sarif 

說明:returntocorp/semgrep-action 會輸出 semgrep.sarif,上傳到「Security → Code scanning alerts」,讓風險出現在 Pull Request 介面。

八、常見踩雷與最佳實務

  • 誤報多:調整規則嚴重度(severity)、增加白名單與 pattern-not 篩除;逐步導入基準線。
  • 掃描太慢:使用 .semgrepignore、限定子資料夾、在 PR 僅掃變更檔(--changed)。
  • 團隊落地:在 PR 強制通過掃描、提供 autofix 規則,並設計「高風險類型」必修清單(SQL/命令注入、XSS、敏感資訊)。

九、與其他 SAST/檢測工具比較

工具 定位/長項 優點 可能限制 適合用戶
Semgrep 快速 SAST / 可自寫規則 輕量、速度快、規則好寫、可本機 深層跨框架資料流需調規則;需治理誤報 想快速導入、重視開發者體驗的團隊
GitHub CodeQL 語意/資料流分析強、與 GitHub 安全整合 深度查找 0-day 類型缺陷、PR 原生整合 學習 QL 語言、掃描時間較長 使用 GitHub、要深度資料流的中大型團隊
SonarQube 品質+安全雙模,技術債指標 Dashboard 友善、規則覆蓋廣、歷史趨勢 自管伺服器、調校時間;社群版安全規則有限 想同時管可維護性與安全的企業
Snyk Code 雲端 SAST(AI/ML 輔助) IDE 即時建議、修補指引、與開源/容器同平台 付費為主、需雲端掃描(資料合規考量) DevSecOps 一站式(SCA + SAST + IaC)
GitLab SAST GitLab CI 原生、範本即用 Pipeline 一鍵啟用、報表統一 最佳體驗綁 GitLab 生態;規則彈性有限 已用 GitLab 的團隊
Linters(ESLintPHPStanPylint) 語法/風格/型別靜態檢查 速度快、IDE 友善、能早期防錯 多為品質/錯誤,安全規則較淺 日常 CI 必備,搭配 SAST 使用

十、選型建議:怎麼搭配最有效

  • 基礎層:Linters(ESLint/PHPStan/Pylint)+型別工具(TypeScript/Psalm)先把語法與錯誤率壓低。
  • 安全層:Semgrep 作為「快掃與開發者回饋」;CodeQL/SonarQube 作為「深度與治理」。
  • 平台層:若使用 GitHub/GitLab,啟用其原生安全(Code Scanning / GitLab SAST)以整合報表與治理。
  • 雲端一站式:Snyk(或相似方案)把 SCA(開源依賴)、容器、IaC 與 SAST 放同平台管理。

十一、實戰落地配方(可直接複製)

  • 前端(React/Next):ESLint + TypeScript + Semgrep(JS/TS 規則)+ 依賴掃描(SCA)。
  • PHP(Laravel/CI4):PHPStan/Psalm + Semgrep(PHP 安全)+ 針對 eval()/shell_exec()/SQL/模板 XSS 的 taint 規則。
  • 多語微服務:各語言 Linters + Semgrep 通用規則 + 每日 CodeQL 深掃(夜間 Pipeline)。

十二、常見問答(FAQ)

  • Q:Semgrep 誤報怎麼降? A:使用 .semgrepignore、加入 pattern-not、善用 --baseline-commit,並在規則中加型別/函式名稱限制。
  • Q:會不會太多工具很麻煩? A:以「層級」思維導入:Linters(快)→ Semgrep(快+安全)→ CodeQL/Sonar(深)。報表集中在一個平台(GitHub/GitLab/SIEM)。
  • Q:本機與 CI 用一套規則? A:可以。建議本機用較寬鬆、CI 用較嚴格;或同一份規則以 severity 控管阻斷門檻。

結語

Semgrep 的價值在於「讓開發者願意每天用」,再把深度分析交給 CodeQL/SonarQube 等工具。以「快掃+深掃」雙軌治理,你能同時兼顧交付速度與安全品質。從今天開始,先在專案加入 semgrep scan --config p/owasp-top-ten,讓每一次提交的安全品質都有依據。