mcpField
I
implementing-semgrep-for-custom-sast-rules

implementing-semgrep-for-custom-sast-rules

github.com/mukul975セキュリティ35.2k182 回インストール8 週間前に更新
リポジトリ

implementing-semgrep-for-custom-sast-rules について

Semgrep のカスタム SAST ルールを導入するアプリケーションセキュリティおよび開発チーム向けのガイドです。YAML でのルール作成、テスト、CI/CD 連携を扱います。

主な機能

  1. 01カスタム YAML ルールの作成
  2. 02パターンと taint 解析の利用
  3. 03ルールテストと修正案の提示
  4. 04GitHub Actions と GitLab CI の連携

活用シーン

  1. 01組織固有のセキュリティ問題の検出
  2. 02CI で重大な検出結果をブロック
  3. 03コーディング規約の適用

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill implementing-semgrep-for-custom-sast-rules

インストール後、Claude Code で/implementing-semgrep-for-custom-sast-rulesを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

LICENSE
references/
api-reference.md
standards.md
scripts/
agent.py

詳細

カスタム SAST ルールの Semgrep 実装

概要

Semgrep は、パターンマッチングを使用してバグを発見し、コーディング規約を適用し、セキュリティ上の脆弱性を検出するオープンソースの静的解析ツールです。カスタムルールは Semgrep のパターン構文を使って YAML で記述するため、コンパイラーの知識がなくても利用できます。Python、JavaScript、Go、Java、C など、30 以上の言語をサポートしています。

使用する場面

  • 環境において、カスタム SAST ルール向けの Semgrep 機能を導入または設定する場合
  • コンプライアンス要件に沿ったセキュリティ制御を確立する場合
  • この分野のセキュリティアーキテクチャを構築または改善する場合
  • この実装を必要とするセキュリティ評価を実施する場合

前提条件

  • Python 3.8+ または Docker
  • Semgrep CLI がインストールされていること
  • サポート対象の言語で書かれた対象コードベース

インストール

# Install via pip
pip install semgrep

# Install via Homebrew
brew install semgrep

# Run via Docker
docker run -v "${PWD}:/src" returntocorp/semgrep semgrep --config auto /src

# Verify
semgrep --version

Semgrep の実行

# Auto-detect rules for your code
semgrep --config auto .

# Use Semgrep registry rules
semgrep --config r/python.lang.security

# Use custom rule file
semgrep --config my-rules.yaml .

# Use multiple configs
semgrep --config auto --config ./custom-rules/ .

# JSON output
semgrep --config auto --json . > results.json

# SARIF output for GitHub
semgrep --config auto --sarif . > results.sarif

# Filter by severity
semgrep --config auto --severity ERROR .

カスタムルールの作成

基本的なパターンマッチング
# rules/sql-injection.yaml
rules:
  - id: sql-injection-string-format
    languages: [python]
    severity: ERROR
    message: |
      Potential SQL injection via string formatting.
      Use parameterized queries instead.
    pattern: |
      cursor.execute(f"..." % ...)
    metadata:
      cwe: ["CWE-89"]
      owasp: ["A03:2021"]
      category: security
    fix: |
      cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
パターン演算子
rules:
  - id: hardcoded-secret-in-code
    languages: [python, javascript, typescript]
    severity: ERROR
    message: Hardcoded secret detected in source code
    patterns:
      - pattern-either:
          - pattern: $VAR = "..."
          - pattern: $VAR = '...'
      - metavariable-regex:
          metavariable: $VAR
          regex: (?i)(password|secret|api_key|token|aws_secret)
      - pattern-not: $VAR = ""
      - pattern-not: $VAR = "changeme"
      - pattern-not: $VAR = "PLACEHOLDER"
    metadata:
      cwe: ["CWE-798"]
      category: security
汚染解析
rules:
  - id: xss-taint-tracking
    languages: [python]
    severity: ERROR
    message: User input flows to HTML response without sanitization
    mode: taint
    pattern-sources:
      - pattern: request.args.get(...)
      - pattern: request.form.get(...)
      - pattern: request.form[...]
    pattern-sinks:
      - pattern: return render_template_string(...)
      - pattern: Markup(...)
    pattern-sanitizers:
      - pattern: bleach.clean(...)
      - pattern: escape(...)
    metadata:
      cwe: ["CWE-79"]
      owasp: ["A03:2021"]
複数言語のルール
rules:
  - id: insecure-random
    languages: [python, javascript, go, java]
    severity: WARNING
    message: |
      Using insecure random number generator. Use cryptographically
      secure alternatives for security-sensitive operations.
    pattern-either:
      # Python
      - pattern: random.random()
      - pattern: random.randint(...)
      # JavaScript
      - pattern: Math.random()
      # Go
      - pattern: math/rand.Intn(...)
      # Java
      - pattern: new java.util.Random()
    metadata:
      cwe: ["CWE-330"]
コーディング規約の適用
rules:
  - id: require-error-handling
    languages: [go]
    severity: WARNING
    message: Error return value not checked
    pattern: |
      $VAR, _ := $FUNC(...)
    fix: |
      $VAR, err := $FUNC(...)
      if err != nil {
        return fmt.Errorf("$FUNC failed: %w", err)
      }

  - id: no-console-log-in-production
    languages: [javascript, typescript]
    severity: WARNING
    message: Remove console.log before merging to production
    pattern: console.log(...)
    paths:
      exclude:
        - "tests/*"
        - "*.test.*"
JWT セキュリティルール
rules:
  - id: jwt-none-algorithm
    languages: [python]
    severity: ERROR
    message: JWT decoded without algorithm verification - allows token forgery
    patterns:
      - pattern: jwt.decode($TOKEN, ..., algorithms=["none"], ...)
    metadata:
      cwe: ["CWE-347"]

  - id: jwt-no-verification
    languages: [python]
    severity: ERROR
    message: JWT decoded with verification disabled
    patterns:
      - pattern: jwt.decode($TOKEN, ..., options={"verify_signature": False}, ...)
    metadata:
      cwe: ["CWE-345"]

ルールのテスト

# rules/test-sql-injection.yaml
rules:
  - id: sql-injection-format-string
    languages: [python]
    severity: ERROR
    message: SQL injection via format string
    pattern: |
      cursor.execute(f"...{$VAR}...")

# Test annotation in test file:
# test-sql-injection.py
def bad_query(user_id):
    # ruleid: sql-injection-format-string
    cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")

def good_query(user_id):
    # ok: sql-injection-format-string
    cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
# Run rule tests
semgrep --test rules/

# Test specific rule
semgrep --config rules/sql-injection.yaml --test

CI/CD との統合

GitHub Actions
name: Semgrep SAST
on: [pull_request]

jobs:
  semgrep:
    runs-on: ubuntu-latest
    container:
      image: returntocorp/semgrep
    steps:
      - uses: actions/checkout@v4

      - name: Run Semgrep
        run: |
          semgrep --config auto \
            --config ./custom-rules/ \
            --sarif --output results.sarif \
            --severity ERROR \
            .

      - name: Upload SARIF
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: results.sarif
GitLab CI
semgrep:
  stage: test
  image: returntocorp/semgrep
  script:
    - semgrep --config auto --config ./custom-rules/ --json --output semgrep.json .
  artifacts:
    reports:
      sast: semgrep.json

設定ファイル

# .semgrep.yaml
rules:
  - id: my-org-rules
    # ... rules here

# .semgrepignore
tests/
node_modules/
vendor/
*.min.js

ベストプラクティス

  1. 自動設定から始め、組織固有のパターンに合わせてカスタムルールを追加します
  2. # ruleid: および # ok: アノテーションを使ってルールをテストします
  3. XSS、SQLi、SSRF などのデータフローの脆弱性には、汚染モードを使用します
  4. 脆弱性の分類に向けて、CWE や OWASP などのメタデータを含めます
  5. 可能な場合は、fix キーを使って修正案を提示します
  6. 誤検知を減らすため、テストファイルを除外します
  7. 共有リポジトリでルールをバージョン管理します
  8. ERROR 重大度の検出結果をブロックするチェックとして、CI で実行します

コメント