semgrep-rule-creator について
防御的なセキュリティ分析やコーディング規約の適用に向けて、Semgrep ルールの作成と検証を支援するスキルです。構造的なパターン照合、 taint 追跡、テスト、誤検知の抑制を扱います。
主な機能
- 01Semgrepの構造的パターン作成
- 02taintモードのソースとシンク定義
- 03インラインの正例・負例テスト
- 04ルールのメタデータと重大度設定
- 05性能と誤検知の確認
活用シーン
- 01自社コードの脆弱性パターン検出
- 02CI/CDでのコーディング規約適用
- 03安全・脆弱なサンプルを使ったルールテスト
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ oimiragieo/ agent-studio --skill semgrep-rule-creatorインストール後、Claude Code で/semgrep-rule-creatorを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
commands/semgrep-rule-creator.mdhooks/post-execute.cjspre-execute.cjsreferences/research-requirements.mdrules/semgrep-rule-creator.mdschemas/input.schema.jsonoutput.schema.jsonscripts/main.cjstemplates/implementation-template.md詳細
Semgrep ルール作成者
セキュリティに関する注意事項
許可された用途に限ります:これらのスキルは、防御的なセキュリティ分析および許可された調査に使用します。
- 所有するコードベース向けのカスタムセキュリティルールの開発
- 自動チェックによるコーディング規約の適用
- CI/CD セキュリティゲートルールの作成
- 脆弱性パターンの予防を目的とした形式化
- 管理された環境での教育目的
次の目的には決して使用しないでください:
- セキュリティ制御を回避するルールの作成
- 許可なくシステムをスキャンすること
- あらゆる違法行為
ステップ 1:検出目標を定義する
ルールを作成する前に、次の項目を明確に定義します。
- 検出対象:脆弱なコードパターン、または望ましくないコードパターン
- 重要である理由:セキュリティへの影響、または品質上の懸念
- 対象言語:対象とするプログラミング言語
- 真陽性の例:マッチするべきコード
- 真陰性の例:マッチするべきではないコード(安全な代替例)
- 誤検知のリスク:似ているものの、実際には安全なコード
検出目標のテンプレート
## Rule: [rule-id]
- **Detect**: [description of what to find]
- **Why**: [security impact / quality concern]
- **Languages**: [javascript, typescript, python, etc.]
- **CWE**: [CWE-XXX]
- **OWASP**: [A0X category]
- **True Positive**: [code example that should match]
- **True Negative**: [safe code that should NOT match]
ステップ 2:Semgrep ルールを作成する
基本的なルール構造
rules:
- id: rule-id-here
message: >
Clear description of what was found and why it matters.
Include remediation guidance in the message.
severity: ERROR # ERROR, WARNING, INFO
languages: [javascript, typescript]
metadata:
cwe:
- CWE-089
owasp:
- A03:2021
confidence: HIGH # HIGH, MEDIUM, LOW
impact: HIGH # HIGH, MEDIUM, LOW
category: security
subcategory:
- vuln
technology:
- express
- node.js
references:
- https://owasp.org/Top10/A03_2021-Injection/
source-rule-url: https://semgrep.dev/r/rule-id
# Pattern goes here (see below)
パターンの種類
単純なパターンマッチ
pattern: |
eval($X)
選択肢を含むパターン(OR)
pattern-either:
- pattern: eval($X)
- pattern: new Function($X)
- pattern: setTimeout($X, ...)
- pattern: setInterval($X, ...)
除外を含むパターン(AND NOT)
patterns:
- pattern: $DB.query($QUERY)
- pattern-not: $DB.query($QUERY, $PARAMS)
- pattern-not: $DB.query($QUERY, [...])
コンテキスト内のパターン
patterns:
- pattern: $RES.send($DATA)
- pattern-inside: |
app.$METHOD($PATH, function($REQ, $RES) {
...
})
- pattern-not-inside: |
app.$METHOD($PATH, authenticate, function($REQ, $RES) {
...
})
メタ変数の制約
patterns:
- pattern: crypto.createHash($ALGO)
- metavariable-regex:
metavariable: $ALGO
regex: (md5|sha1|MD5|SHA1)
- focus-metavariable: $ALGO
patterns:
- pattern: setTimeout($FUNC, $TIME)
- metavariable-comparison:
metavariable: $TIME
comparison: $TIME > 60000
汚染モードルール(上級)
ソースからシンクへのデータフローを追跡するには、次のようにします。
mode: taint
pattern-sources:
- patterns:
- pattern: $REQ.query.$PARAM
- patterns:
- pattern: $REQ.body.$PARAM
- patterns:
- pattern: $REQ.params.$PARAM
pattern-sinks:
- patterns:
- pattern: $DB.query($SINK, ...)
- focus-metavariable: $SINK
pattern-sanitizers:
- patterns:
- pattern: escape($X)
- patterns:
- pattern: sanitize($X)
- patterns:
- pattern: $DB.query($QUERY, [...])
ステップ 3:一般的なルールのテンプレート
SQL インジェクションの検出
rules:
- id: sql-injection-string-concat
message: >
Possible SQL injection via string concatenation. User input appears
to be concatenated into a SQL query string. Use parameterized
queries instead.
severity: ERROR
languages: [javascript, typescript]
metadata:
cwe: [CWE-089]
owasp: [A03:2021]
confidence: HIGH
impact: HIGH
category: security
patterns:
- pattern-either:
- pattern: $DB.query("..." + $VAR + "...")
- pattern: $DB.query(`...${$VAR}...`)
- pattern-not: $DB.query("..." + $VAR + "...", [...])
fix: |
$DB.query("... $1 ...", [$VAR])
XSS の検出
rules:
- id: xss-innerhtml-assignment
message: >
Direct assignment to innerHTML with potentially untrusted data.
Use textContent for text or a sanitization library for HTML.
severity: ERROR
languages: [javascript, typescript]
metadata:
cwe: [CWE-079]
owasp: [A03:2021]
confidence: MEDIUM
impact: HIGH
category: security
pattern-either:
- pattern: $EL.innerHTML = $DATA
- pattern: document.getElementById($ID).innerHTML = $DATA
ハードコードされたシークレット
rules:
- id: hardcoded-api-key
message: >
Hardcoded API key detected. Store secrets in environment
variables or a secrets manager.
severity: ERROR
languages: [javascript, typescript, python]
metadata:
cwe: [CWE-798]
owasp: [A02:2021]
confidence: MEDIUM
impact: HIGH
category: security
pattern-either:
- pattern: |
$KEY = "AKIA..."
- pattern: |
$KEY = "sk-..."
- pattern: |
$KEY = "ghp_..."
pattern-regex: (AKIA[0-9A-Z]{16}|sk-[a-zA-Z0-9]{48}|ghp_[a-zA-Z0-9]{36})
認証の欠如
rules:
- id: express-route-missing-auth
message: >
Express route handler without authentication middleware.
Add authentication middleware before the handler.
severity: WARNING
languages: [javascript, typescript]
metadata:
cwe: [CWE-306]
owasp: [A07:2021]
confidence: MEDIUM
impact: HIGH
category: security
patterns:
- pattern-either:
- pattern: app.post($PATH, function($REQ, $RES) { ... })
- pattern: app.put($PATH, function($REQ, $RES) { ... })
- pattern: app.delete($PATH, function($REQ, $RES) { ... })
- pattern: router.post($PATH, function($REQ, $RES) { ... })
- pattern: router.put($PATH, function($REQ, $RES) { ... })
- pattern: router.delete($PATH, function($REQ, $RES) { ... })
- pattern-not-inside: |
app.$METHOD($PATH, $AUTH, function($REQ, $RES) { ... })
- pattern-not-inside: |
router.$METHOD($PATH, $AUTH, function($REQ, $RES) { ... })
安全でない乱数生成
rules:
- id: insecure-random-for-security
message: >
Math.random() is not cryptographically secure. Use
crypto.getRandomValues() or crypto.randomBytes() for
security-sensitive random values.
severity: WARNING
languages: [javascript, typescript]
metadata:
cwe: [CWE-330]
confidence: MEDIUM
impact: MEDIUM
category: security
patterns:
- pattern: Math.random()
- pattern-inside: |
function $FUNC(...) {
...
}
- metavariable-regex:
metavariable: $FUNC
regex: (generateToken|createSecret|randomPassword|generateKey|createSession|generateId|createNonce)
ステップ 4:ルールのテストを作成する
テストファイルの形式
ルールと同じ場所にテストファイルを作成します。
// ruleid: sql-injection-string-concat
db.query('SELECT * FROM users WHERE id = ' + userId);
// ruleid: sql-injection-string-concat
db.query(`SELECT * FROM users WHERE id = ${userId}`);
// ok: sql-injection-string-concat
db.query('SELECT * FROM users WHERE id = $1', [userId]);
// ok: sql-injection-string-concat
db.query('SELECT * FROM users WHERE id = ?', [userId]);
テストの実行
# Test a single rule
semgrep --test --config=rules/sql-injection.yml tests/
# Test all rules
semgrep --test --config=rules/ tests/
# Validate rule syntax
semgrep --validate --config=rules/
ステップ 5:ルールを最適化する
パフォーマンスに関するベストプラクティス
- パターンを具体的にする:
$X($Y)のように範囲が広すぎるマッチは避けます - pattern-inside を使って対象範囲を絞る:検索コンテキストを限定します
- 言語固有の構文を使う:言語の機能を活用します
- 深い省略記号の入れ子を避ける:
... ... ...は遅くなります - focus-metavariable を使う:報告される位置を絞り込みます
- 大規模なコードベースでテストする:大規模環境でパフォーマンスを確認します
誤検知の削減
- pattern-not を追加して安全なパターンを指定する:既知の安全な代替手段を除外します
- metavariable-regex を使う:メタ変数の値を制約します
- pattern-not-inside を使う:安全なコンテキストを除外します
- 適切な信頼度を設定する:検出の確実性を正直に示します
- 技術メタデータを追加する:ユーザーが関連するルールを絞り込めるようにします
- 修正案を提示する:可能な場合は
fix:フィールドを含めます
ルール検証チェックリスト
- ルールに一意で説明的な ID がある
- メッセージで問題とその修正方法の両方を説明している
- 深刻度が実際のリスクに合っている
- メタデータに CWE、OWASP、信頼度、影響が含まれている
- 真陽性のテストケースが少なくとも 2 件ある
- 真陰性のテストケースが少なくとも 2 件ある
-
semgrep --validateでルールを検証している -
semgrep --testでルールをテストしている - 大規模なコードベースでもパフォーマンスが許容範囲内である
- 該当する場合は修正案を提示している
Semgrep パターン構文リファレンス
| 構文 | 意味 | 例 |
|---|---|---|
$X | 単一のメタ変数 | eval($X) |
$...X | 複数のメタ変数引数 | func($...ARGS) |
... | 省略記号(任意のステートメント) | if (...) { ... } |
<... $X ...> | 深い式のマッチ | <... eval($X) ...> |
pattern-either | OR 演算子 | N 個のパターンのいずれかに一致 |
pattern-not | NOT 演算子 | 特定のパターンを除外 |
pattern-inside | コンテキスト要件 | このパターン内に存在する必要がある |
pattern-not-inside | コンテキスト除外 | このパターン内に存在してはならない |
metavariable-regex | 正規表現の制約 | $X が正規表現に一致するよう制約する |
metavariable-comparison | 数値の制約 | $X > 100 |
focus-metavariable | マッチ位置を絞り込む | $X の位置のみを報告する |
関連スキル
static-analysis- SARIF 出力による CodeQL と Semgrepvariant-analysis- パターンベースの脆弱性発見differential-review- セキュリティに重点を置いた差分分析insecure-defaults- ハードコードされた認証情報の検出security-architect- STRIDE 脅威モデリング
エージェントとの連携
- security-architect(主担当):セキュリティ監査向けのカスタムルール開発
- code-reviewer(主担当):自動コードレビュー用ルールの作成
- penetration-tester(副担当):脆弱性検出ルールの作成
- qa(副担当):品質を担保するルールの作成
絶対に守るべき原則
- 真陽性と真陰性のテストケースをそれぞれ少なくとも 2 件用意せずに、ルールを決して公開しないでください
- コミットする前に、
semgrep --validateでルールの構文を必ず検証してください - 実際のコードベースでルールをテストせずに、信頼度を HIGH に決して設定しないでください
- すべてのルールメッセージに、何が見つかったか、なぜ重要か、どう修正するかを必ず含めてください
- 主なマッチャーとして
pattern-regexを決して使わないでください。構造パターンを使い、metavariable-regexで制約してください
アンチパターン
| アンチパターン | 失敗する理由 | 正しいアプローチ |
|---|---|---|
| テストしていないルールを公開する | 誤検知によって開発者の信頼が損なわれ、ルールが無視されます | // ruleid: と // ok: の注釈を使ってテストケースを作成し、semgrep --test を実行します |
| 検証せずに HIGH の信頼度を設定する | 自信過剰なルールにより、レビュー担当者が誤ったシグナルを信頼してしまいます | 実際のコードベースで測定した誤検知率に基づいて信頼度を調整します |
| 曖昧なルールメッセージ | 具体的な指針がなければ、開発者は問題を修正できません | すべてのメッセージに、検出されたもの、重要な理由、修正方法を含めます |
| 除外条件のない広すぎるパターン | 誤検知率が高くなり、ルール疲れを引き起こします | 既知の安全な代替手段すべてに対して pattern-not 句を追加します |
主なマッチャーとして pattern-regex を使う | 正規表現は構造パターンマッチングより遅く、精度も低くなります | 構造パターンを主に使用し、metavariable-regex だけで絞り込みます |
メモリプロトコル(必須)
開始前:
.claude/context/memory/learnings.md を読みます。
完了後:
- 新しいパターン ->
.claude/context/memory/learnings.md - 発見した問題 ->
.claude/context/memory/issues.md - 決定事項 ->
.claude/context/memory/decisions.md
中断されることを想定してください。メモリに記録されていないことは、起きていないのと同じです。
相互参照:Creator エコシステム
このスキルは Creator エコシステム の一部です。調査で不足が明らかになった場合は、適切な関連クリエーターを呼び出してください。
| 発見された不足 | 必要な成果物 | 呼び出すクリエーター | 呼び出すタイミング |
|---|---|---|---|
| ドメイン知識に再利用可能なスキルが必要 | skill | Skill({ skill: 'skill-creator' }) | 不足がスキルの領域全体に及ぶ場合 |
| 既存のスキルのカバー範囲が不完全 | skill update | Skill({ skill: 'skill-updater' }) | 関連するスキルはあるが、不完全な場合 |
| 機能に専用エージェントが必要 | agent | Skill({ skill: 'agent-creator' }) | 機能を担うエージェントが必要な場合 |
| 既存のエージェントに機能の更新が必要 | agent update | Skill({ skill: 'agent-updater' }) | 関連するエージェントはあるが、不完全な場合 |
| ドメインにコード/プロジェクトのひな形が必要 | template | Skill({ skill: 'template-creator' }) | 再利用可能なコードパターンが必要な場合 |
| 動作に実行前/実行後のガードが必要 | hook | Skill({ skill: 'hook-creator' }) | 強制適用が必要な動作がある場合 |
| プロセスに複数フェーズのオーケストレーションが必要 | workflow | Skill({ skill: 'workflow-creator' }) | 複数ステップの調整が必要な場合 |
| 成果物に構造化された入出力の検証が必要 | schema | Skill({ skill: 'schema-creator' }) | 成果物の入出力に JSON スキーマが必要な場合 |
| ユーザー操作にスラッシュコマンドが必要 | command | Skill({ skill: 'command-creator' }) | ユーザー向けのショートカットが必要な場合 |
| 繰り返し使うロジックに再利用可能な CLI ツールが必要 | tool | Skill({ skill: 'tool-creator' }) | CLI ユーティリティが必要な場合 |
| 範囲が狭い/単一成果物のみを扱う機能 | inline | この成果物内だけに記述する | 一般化するには具体的すぎる場合 |
エコシステム連携契約(必須)
このクリエイタースキルは、連携するクリエイターエコシステムの一部です。ここで作成する成果物は、関連する以下のクリエイターとの整合性を保ち、検証できる必要があります。
- 所有権と実行経路については
agent-creator - 機能のパッケージ化と割り当てについては
skill-creator - 実行可能な自動化のインターフェースについては
tool-creator - 強制とガードレールについては
hook-creator - ポリシーと静的チェックについては
rule-creatorとsemgrep-rule-creator - 標準化されたひな形については
template-creator - オーケストレーションとフェーズのゲーティングについては
workflow-creator - ユーザー/オペレーター向けコマンドの UX については
command-creator
クリエイター間の連携手順(必須)
完了前に、関連するすべての連携事項を確認してください。
- 成果物へのルートが
.claude/CLAUDE.mdおよび関連するルーティングドキュメントに存在すること。 - ディスカバリー/レジストリのエントリーが更新されていること(該当する場合、カタログ/インデックス/レジストリ)。
- 関連成果物が作成されていること、または理由を明記して作成を明示的に免除していること。
- 作成した成果物について
validate-integration.cjsが成功すること。 - スキルのメタデータを変更した場合、スキルインデックスが再生成されていること。
調査ゲート(Exa + arXiv — 両方必須)
新しいパターン、テンプレート、ワークフローを作成する場合、調査は必須です。
- 実装とエコシステムのパターンを調べるには Exa を使用してください。
mcp__Exa__web_search_exa({ query: '<topic> 2025 best practices' })mcp__Exa__get_code_context_exa({ query: '<topic> implementation examples' })
- 学術研究を調べるには arXiv を検索してください(AI/ML、エージェント、評価、オーケストレーション、メモリ/RAG、セキュリティに関して必須)。
- Exa 経由:
mcp__Exa__web_search_exa({ query: 'site:arxiv.org <topic> 2024 2025' }) - 直接 API:
WebFetch({ url: 'https://arxiv.org/search/?query=<topic>&searchtype=all&start=0' })
- Exa 経由:
- 判断、制約、対象外事項を成果物の参照資料/ドキュメントに記録してください。
- 更新は最小限にとどめ、過剰な設計は避けてください。
トピックに次のいずれかが含まれる場合、arXiv の検索は必須です(代替手段ではありません): AI エージェント、LLM 評価、オーケストレーション、メモリ/RAG、セキュリティ、静的解析、または新たな方法論。
リグレッションに安全なデリバリー
- 動作の変更には、厳格な RED → GREEN → REFACTOR の手順に従ってください。
- 変更したモジュールに対象を絞ったテストを実行してください。
- 変更したファイルに対して lint/フォーマットを実行してください。
- コミットは関心事ごとに範囲を限定してください(ロジック/ドキュメント/生成された成果物)。