mcpField
O
opengrep-rule-generator-research

opengrep-rule-generator-research

github.com/security-phoenix-demoセキュリティ8146 回インストール7 週間前に更新
リポジトリ

opengrep-rule-generator-research について

対話による要件整理や脆弱性調査を通じて、opengrep/semgrep の YAML セキュリティルールを作成するスキルです。ルール方式の選定からテストや検証までを扱います。

主な機能

  1. 01対話形式でのルール要件整理
  2. 02CVE、CWE、OWASPからの生成
  3. 03検索モードと taint モードの選択
  4. 04誤検知を減らすための指針
  5. 05ルールテストと検証チェックリスト

活用シーン

  1. 01コードの脆弱性を検出するルール作成
  2. 02CVEを検出パターンに変換
  3. 03コードベースのセキュリティ問題のスキャン

インストール

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

$npx skills add https://github.com/security-phoenix-demo/security-skills-claude-code --skill opengrep-rule-generator-research

インストール後、Claude Code で/opengrep-rule-generator-researchを入力して読み込まれたか確認します。

同梱ファイル

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

OPENGREP_RULE_GENERATOR_PROMPT.md
README.md
RULES_SYNTAX.md

詳細

Opengrep ルールジェネレーター

概要

共同で対話しながら、有効な opengrep/semgrep YAML ルールを生成します。2 つのワークフローに対応しています。ガイド付き(検出対象を見つけるための対話形式の Q&A)と、脆弱性主導型(CVE、OWASP カテゴリー、または脆弱性の説明を基にルールを自動生成)です。

使用するタイミング

  • ユーザーが「ルールを作成して」「ルールを書いて」「ルールを生成して」「[脆弱性]を検出して」と言う場合
  • ユーザーが CVE、CWE、または OWASP の参照情報を提示し、検出ルールを求める場合
  • ユーザーがコードスニペットを共有し、「このパターンをどう検出できますか?」と尋ねる場合
  • ユーザーが、特定の種類の脆弱性についてコードベースをスキャンしたい場合
  • ユーザーがセキュリティ問題のコード監査を依頼し、再利用可能なルールを求める場合

プロセスフロー

digraph rule_gen {
    "User request" [shape=doublecircle];
    "Has specific vulnerability?" [shape=diamond];
    "Guided Discovery" [shape=box];
    "Vulnerability-Driven" [shape=box];
    "Gather context" [shape=box];
    "Choose rule mode" [shape=diamond];
    "Generate Search rule" [shape=box];
    "Generate Taint rule" [shape=box];
    "Present rule for review" [shape=box];
    "User approves?" [shape=diamond];
    "Write rule file" [shape=box];
    "Generate test file" [shape=box];
    "Validate with opengrep" [shape=doublecircle];

    "User request" -> "Has specific vulnerability?";
    "Has specific vulnerability?" -> "Vulnerability-Driven" [label="yes"];
    "Has specific vulnerability?" -> "Guided Discovery" [label="no"];
    "Guided Discovery" -> "Gather context";
    "Vulnerability-Driven" -> "Gather context";
    "Gather context" -> "Choose rule mode";
    "Choose rule mode" -> "Generate Search rule" [label="pattern match"];
    "Choose rule mode" -> "Generate Taint rule" [label="data flow"];
    "Generate Search rule" -> "Present rule for review";
    "Generate Taint rule" -> "Present rule for review";
    "Present rule for review" -> "User approves?";
    "User approves?" -> "Present rule for review" [label="revise"];
    "User approves?" -> "Write rule file" [label="yes"];
    "Write rule file" -> "Generate test file";
    "Generate test file" -> "Validate with opengrep";
}

参考ドキュメント

ルールを生成する前に、以下のプロジェクトドキュメントからコンテキストを読み込んでください。

ドキュメントパス読み込むタイミング
ルールの構文とテンプレートdocs/ai/RULES_SYNTAX.md常に — すべての演算子、テンプレート、言語 ID が記載されています
ルールインデックスdocs/ai/RULES_INDEX.md既存の類似ルールを確認するとき
エンジンの内部構造docs/ai/RULES_ENGINE.mdsearch モードと taint モードのどちらを選ぶか決めるとき

また、類似のパターンについて既存のルールも検索してください。

  • semgrep-rules/semgrep-rules/<language>/ — コミュニティルール
  • semgrep-rules-trailbits/<language>/ — Trail of Bits のルール

ワークフロー 1:ガイド付きの探索

ルールの範囲を絞り込むため、以下の質問を1 つずつ尋ねます。

ステップ 1 — 何を検出しますか?
What vulnerability, bug pattern, or coding anti-pattern do you want to detect?

Examples:
- "SQL injection in our Flask app"
- "Hardcoded secrets in config files"
- "Missing null checks after API calls"
- "Insecure deserialization"
- "Race conditions in Go goroutines"
ステップ 2 — 使用する言語とフレームワークは何ですか?
What programming language(s) and frameworks are involved?

I support 30+ languages including: python, javascript, typescript, java, go,
ruby, php, csharp, c, rust, scala, kotlin, swift, terraform/hcl, yaml,
dockerfile, solidity, and more. I also support 'generic' for config files
and 'regex' for raw text matching.
ステップ 3 — 脆弱なコードを見せてください
Can you show me an example of the VULNERABLE code you want to catch?
And if possible, also show the SAFE version (the fix)?

This helps me write precise patterns with fewer false positives.
ステップ 4 — ユーザー入力はどこから入りますか?(該当する場合)
Does this vulnerability involve untrusted user input flowing into a dangerous function?

If yes, I'll use TAINT MODE (tracks data flow from sources to sinks).
If no, I'll use SEARCH MODE (structural pattern matching).

For taint mode, I need to know:
- Sources: Where does untrusted data come from? (HTTP requests, file reads, env vars, etc.)
- Sinks: Where is it dangerous? (SQL queries, system commands, file writes, etc.)
- Sanitizers: What makes the data safe? (escaping, validation, type casting, etc.)
ステップ 5 — 重大度と対象範囲
How severe is this issue?
- CRITICAL/ERROR: Exploitable vulnerability, must fix
- WARNING/MEDIUM: Likely vulnerability, should fix
- INFO/LOW: Code smell or audit flag

Should the rule apply to all files, or specific paths only?

ワークフロー 2:脆弱性主導型の生成

CVE、CWE、OWASP カテゴリー、または脆弱性の説明が提示された場合:

  1. 脆弱性を調査する — 以下の調査計画を使って、全体像を把握します
  2. 脆弱性を分析する — 対象言語、脆弱な API/パターン、攻撃ベクトル、修正方法を抽出します
  3. 既存のルールを確認する — semgrep-rules/ と semgrep-rules-trailbits/ を検索して、対応状況を確認します
  4. ルールモードを決定する:
    • 入力から危険な関数へデータが流れる → Taint モード
    • 危険な関数呼び出しまたは設定パターン → Search モード
    • AST を使わないテキスト/設定パターン → Regex/generic モード
  5. ルールを生成する — 異なる攻撃パターンに対して複数のルールを生成する場合があります
  6. 説明を添えて提示する — 各ルールで検出できるものと既知の制限を説明します
脆弱性の調査計画

包括的に網羅できるよう、ルールを生成する前に調査を行ってください。WebSearch と WebFetch のツールを使用します。

フェーズ 1 — 脆弱性を理解する:

  • "<CVE/CWE ID>" vulnerability details を検索して、公式の説明を確認します
  • "<vulnerability type>" <language> exploit examples を検索して、実際の攻撃パターンを確認します
  • CWE エントリー https://cwe.mitre.org/data/definitions/<ID>.html を取得し、分類、関連する弱点、検出方法を確認します
  • 該当するカテゴリーの OWASP ページを取得します(例:https://owasp.org/Top10/A03_2021-Injection/)

フェーズ 2 — 言語固有の攻撃対象領域を特定する:

  • "<vulnerability>" <framework> cheat sheet site:cheatsheetseries.owasp.org を検索します
  • "<vulnerability>" <framework> security best practices を検索します
  • エントリーポイント(ソース)、危険な API(シンク)、安全な代替手段(サニタイザー)を特定します
  • "<vulnerable function>" CVE を検索し、そのパターンを示す実際の CVE を探します

フェーズ 3 — 既存の検出方法を調べる:

  • semgrep rule "<vulnerability type>" <language> を検索して、コミュニティルールを確認します
  • semgrep-rules/ と semgrep-rules-trailbits/ ディレクトリ内の既存ルールを検索します
  • 対応済みの範囲と、残されているギャップを記録します

フェーズ 4 — 調査結果を記録する: ルールファイルの先頭に、YAML コメントブロックとして簡潔な調査概要を記述します。

# Research: <vulnerability type> in <language/framework>
# Sources: <where untrusted data enters>
# Sinks: <where data becomes dangerous>
# Sanitizers: <what makes data safe>
# References researched:
#   - <url1>
#   - <url2>
# Coverage gaps found: <what existing rules miss>
モード選択ガイド
脆弱性の種類ルールモード理由
SQL インジェクション汚染追跡ユーザー入力 → クエリ関数
XSS汚染追跡ユーザー入力 → HTML 出力
コマンドインジェクション汚染追跡ユーザー入力 → exec/system
SSRF汚染追跡ユーザー入力 → HTTP リクエスト
パストラバーサル汚染追跡ユーザー入力 → ファイル操作
ハードコードされたシークレット検索 + 正規表現リテラルのパターンマッチ
安全でない設定検索設定の構造パターン
認証チェックの欠落検索(内側/内側でない)パターンの不在
競合状態検索(内側 + 内側でない)ゴルーチン/スレッド内のパターン
弱い暗号化検索特定の API 呼び出し
デシリアライズ検索または汚染追跡入力が制御されているかどうかによる
Terraform の設定ミス検索HCL の構造パターン

ルール生成テンプレート

ルールを生成するときは、必ず以下の完全な構造を出力します。

rules:
  - id: <company-or-project>-<language>-<vuln-type>
    message: >-
      <1-3 sentences: what was found, why it's dangerous, how to fix it>
    severity: <ERROR|WARNING|INFO>
    languages: [<language>]
    metadata:
      category: <security|correctness|best-practice|performance>
      cwe:
        - "CWE-XXX: <Description>"
      owasp:                          # include if security rule
        - "A0X:2021 - <Category>"
      references:
        - <url-to-documentation>
      technology:
        - <framework-or-library>
      subcategory:
        - <vuln|audit>
      confidence: <HIGH|MEDIUM|LOW>
      likelihood: <HIGH|MEDIUM|LOW>
      impact: <HIGH|MEDIUM|LOW>
    # ... pattern operators or taint spec ...
命名規則

ルール ID:<scope>-<language>-<vuln-type>[-<variant>]

  • myapp-python-sql-injection
  • myapp-go-race-condition-map-write
  • myapp-java-spring-ssrf
メッセージの品質

優れたメッセージには、以下が含まれます。

  1. 何を検出したか(パターン)
  2. なぜ危険なのか(リスク)
  3. どのように修正するか(修正方法)
message: >-
  User input from `flask.request` is concatenated into a SQL query string
  passed to `cursor.execute()`. This could allow SQL injection, letting an
  attacker read or modify database contents. Use parameterized queries instead:
  `cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))`.

テストファイルの生成

必ず、以下を含む対応するテストファイルを生成します。

# === True Positives (MUST trigger) ===

# ruleid: <rule-id>
<vulnerable code example 1>

# ruleid: <rule-id>
<vulnerable code example 2 — different variant>

# === True Negatives (must NOT trigger) ===

# ok: <rule-id>
<safe code — using the recommended fix>

# ok: <rule-id>
<safe code — different safe pattern>

最低限: ルールごとに、真陽性を 2 件、真陰性を 2 件。

高度なパターンのクックブック

セキュリティチェックの欠落を検出する(pattern-not-inside)
patterns:
  - pattern: dangerous_operation(...)
  - pattern-not-inside: |
      if <... auth_check(...) ...>:
        ...
汚染された文字列の連結を検出する(taint + metavariable-regex)
mode: taint
pattern-sources:
  - pattern: request.args.get(...)
pattern-sinks:
  - patterns:
      - pattern: |
          "$SQLSTR" + ...
      - metavariable-regex:
          metavariable: $SQLSTR
          regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.*
弱い設定値を検出する(metavariable-comparison)
patterns:
  - pattern-inside: |
      resource "aws_s3_bucket" "..." {
        ...
        versioning { days = $DAYS }
        ...
      }
  - metavariable-comparison:
      metavariable: $DAYS
      comparison: $DAYS < 90
複数の呼び出しバリエーションを検出する(pattern-either + metavariable-regex)
patterns:
  - pattern-either:
      - pattern: $OBJ.$METHOD(...)
      - pattern: $MODULE.$METHOD(...)
  - metavariable-regex:
      metavariable: $METHOD
      regex: (eval|exec|compile|unsafe_load)
型制約を使用して検出する(型付きメタ変数)
# Go: match only http.Request types
pattern: ($REQ : *http.Request).$FIELD
ラベルを使用した複数ステップの汚染追跡
mode: taint
pattern-sources:
  - patterns:
      - pattern: request.get_param(...)
    label: USER_INPUT
  - patterns:
      - pattern: $X + $Y
    label: CONCATENATED
    requires: USER_INPUT
pattern-sinks:
  - patterns:
      - pattern: db.execute(...)
    requires: CONCATENATED

誤検知の削減

ルールを生成した後、必ず以下の追加を検討します。

  1. pattern-not — 安全なバリエーションを除外する(リテラル文字列には pattern-not: func("...", ...) を使用)
  2. pattern-not-inside — 安全なコンテキストを除外する(try/catch 内、サニタイズ用ラッパー内など)
  3. metavariable-regex — メタ変数の値を危険なものに制限する
  4. 安全な型の除外 — options: { taint_assume_safe_numbers: true, taint_assume_safe_booleans: true }
  5. ログ/出力の除外 — ログへの誤検知を避けるため、pattern-not-inside: $LOG.info(...) を使用する

検証チェックリスト

ルールを確定する前に、以下を確認します。

  • ルール ID が一意で、ケバブケースに従っている
  • languages フィールドが対象コードに合っている
  • メッセージで何を、なぜ、どのように修正するかを説明している
  • 該当する場合、メタデータに CWE と OWASP が含まれている
  • 真陽性のテストケースが 2 件以上ある
  • 真陰性のテストケースが 2 件以上ある
  • 誤検知を減らす方法を検討している(pattern-not、安全な型のオプション)
  • 利用可能な場合は、opengrep scan --config <rule.yaml> <test-file> でルールをテストしている

一括生成

脆弱性のクラス(例:「Python Flask 向け OWASP Top 10」)のルール生成を依頼された場合:

  1. 該当する脆弱性カテゴリをすべて列挙する
  2. semgrep-rules/ の既存カバレッジを確認する
  3. 不足している項目を特定する
  4. 不足分のルールのみを生成する
  5. 表として提示する:| 脆弱性 | 既存ルール? | 新しいルール ID | モード |

ルール生成の方法論

高品質なルールを生成するには、以下の体系的なプロセスに従います。

1. 脆弱性を深く理解する

関数名だけでパターンマッチングしないでください。 以下を理解します。

  • 何が危険なのか?(症状ではなく根本原因)
  • 攻撃シナリオは何か?(攻撃者はこれをどのように悪用するのか?)
  • データフローはどうなっているか?(ソース → 変換 → シンク)
  • すべてのバリエーションは何か?(文字列連結、書式文字列、テンプレートリテラル、f 文字列)
  • 安全な代替手段は何か?(プレースホルダー付きクエリ、テンプレートエンジン、エスケープ関数)
2. 既存ルールをテンプレートとして調べる

一から作成する前に、類似するパターンの既存ルールを検索します。

semgrep-rules/semgrep-rules/<language>/<framework>/security/
semgrep-rules-trailbits/<language>/

品質の高いルールを読み、そのパターンを応用します。既存ルールからは、以下のことがわかります。

  • 各フレームワークで標準となるソース
  • 誤検知を減らす metavariable-regex パターン
  • pattern-not による除外の構成方法
  • 使用するメタデータフィールドと CWE/OWASP のマッピング
3. ソース・シンク・サニタイザーのマップを作成する

言語/フレームワークごとに、以下を記録します。

コンポーネント例
ソース(ユーザー入力の入り口)request.args、req.query、$_GET、params[:]
シンク(危険な出力箇所)res.send()、echo、innerHTML、cursor.execute()
サニタイザー(安全な変換)escape()、htmlspecialchars()、parseInt()、テンプレートエンジン
プロパゲーター(データ構造内のフロー)StringBuilder.append()、HashMap.put()、array.push()
4. 多層防御パターンでルールを記述する

ルールは段階的に記述します。

  1. 広範な taint ルール — 主要な攻撃経路を検出します
  2. 特定の検索ルール — 危険な API の誤用(例:dangerouslySetInnerHTML)を検出します
  3. 設定/監査ルール — リスクのある設定(例:autoescape off)にフラグを立てます
5. 誤検知を減らすために反復する

最初のルール生成後、次の手順を行います。

  1. 検出対象となりうる、よくある安全なパターンを検討します
  2. 安全なリテラル、安全な型、ログ出力には pattern-not を追加します
  3. try/catch や検証用ラッパーには pattern-not-inside を追加します
  4. taint_assume_safe_numbers: true と taint_assume_safe_booleans: true を設定します
  5. metavariable-regex を使って、危険なメソッド名に絞り込みます
全体のコンテキスト:リファレンスドキュメント

ルールを生成する際は、以下のドキュメントでルールスキーマ全体を確認できます。

必要な情報参照先
すべてのパターン演算子docs/ai/RULES_SYNTAX.md §3-5
taint モード仕様(ソース/シンク/サニタイザー/プロパゲーター/ラベル)docs/ai/RULES_SYNTAX.md §6
メタ変数の条件(正規表現、比較、型、パターン)docs/ai/RULES_SYNTAX.md §4
サポートされているすべての言語docs/ai/RULES_SYNTAX.md §9
ルールテンプレート(8つの完全な例)docs/ai/RULES_SYNTAX.md §12
エンジンによるパターンの照合方法docs/ai/RULES_ENGINE.md §2
taint 解析の内部動作docs/ai/RULES_ENGINE.md §3
言語別の既存ルールのカバレッジdocs/ai/RULES_INDEX.md
CWE/OWASP メタデータの規約docs/ai/RULES_SYNTAX.md §7
ルールオプション(エンジン設定)docs/ai/RULES_SYNTAX.md §8
生成ルールのディレクトリ

生成したルールは、対応するテストファイルとともに custom-rules/<vuln-type>/ に保存します。

custom-rules/
  xss/
    xss-python-flask.yaml     # Rules
    xss-python-flask.py       # Test file
  sqli/
    sqli-java-spring.yaml
    sqli-java-spring.java

よくある間違いとその回避方法

間違い修正方法
パターンの範囲が広すぎる($FUNC(...))metavariable-regex または pattern-inside を追加して範囲を絞ります
関数本体に省略記号がない関数/クラス本体に ... を使い、柔軟に照合できるようにします
安全なバリエーションに対する pattern-not の追加忘れ常に「安全なコードはどのような形か」を検討します
言語 ID が間違っている有効な ID は docs/ai/RULES_SYNTAX.md の Section 9 で確認します
サニタイザーのない taint常に「このデータを安全にするものは何か」を確認し、サニタイザーを追加します
フレームワークのバージョンをハードコードしているバージョンに依存しないパターンには ... を使います
陰性テストをしていない誤検知は信頼を損ないます。安全なコードパスをテストします

コメント