semgrep について
Semgrepによる静的解析を扱うスキルです。コードスキャン、脆弱性パターンの検出、カスタムルール作成を支援し、Semgrep MCPツールがあれば優先し、なければCLIを使います。
主な機能
- 01ルールセットによるコードスキャン
- 02パターン照合と taint ルールの作成
- 03検証前のルールテスト
- 04SARIF または JSON での出力
活用シーン
- 01コードのセキュリティ脆弱性をスキャン
- 02プロジェクト固有のパターンを検出
- 03カスタムルールを作成してテスト
MCP 対応
利用可能な場合、Semgrep MCPツールでコードスキャン、カスタムルールによるスキャン、プラットフォーム上の検出結果の取得、ルールスキーマや対応言語の確認ができます。MCPツールがない場合はCLIを使います。
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ semgrep/ skills --skill semgrepインストール後、Claude Code で/semgrepを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdreferences/quick-reference.mdworkflow.md詳細
Semgrep 静的解析
高速なパターンベースの静的解析で、セキュリティスキャンとカスタムルールの作成に対応します。
利用可能な MCP ツール
環境で Semgrep MCP ツールを利用できる場合は、スキャンに優先して使用してください。
semgrep_scan— 組み込みルールセットを使って、コードファイルのセキュリティ脆弱性をスキャンします。絶対ファイルパスと、任意の設定(例:p/security-audit、auto)を渡します。semgrep_scan_with_custom_rule— 作成したカスタム YAML ルールを使ってコードをスキャンします。ルールとともに、コード内容をインラインで渡します。semgrep_findings— リポジトリについて、Semgrep AppSec Platform から既存の検出結果を取得します。semgrep_rule_schema— Semgrep ルールを作成するための完全なスキーマを取得します。get_supported_languages— Semgrep がサポートするすべての言語を一覧表示します。
MCP ツールを利用できない場合は、以下の CLI コマンドを使用してください。
Semgrep を使用する場面
最適な用途:
- 迅速なセキュリティスキャン(数時間ではなく数分)
- パターンベースのバグや脆弱性の検出
- コーディング規約とベストプラクティスの徹底
- 既知の脆弱性パターン(OWASP、CWE)の検出
- コードベース向けのカスタム検出ルールの作成
- taint モードによるデータフロー解析
インストール(CLI)
# pip (recommended)
python3 -m pip install semgrep
# Homebrew
brew install semgrep
# Docker
docker run --rm -v "${PWD}:/src" semgrep/semgrep semgrep --config auto /src
パート 1:スキャンの実行
クイックスキャン
semgrep --config auto . # Auto-detect rules
ルールセットの使用
semgrep --config p/<RULESET> . # Single ruleset
semgrep --config p/security-audit --config p/trailofbits . # Multiple
| ルールセット | 説明 |
|---|---|
p/default | 一般的なセキュリティとコード品質 |
p/security-audit | 包括的なセキュリティルール |
p/owasp-top-ten | OWASP Top 10 の脆弱性 |
p/cwe-top-25 | CWE Top 25 の脆弱性 |
p/trailofbits | Trail of Bits のセキュリティルール |
p/python | Python 固有 |
p/javascript | JavaScript 固有 |
p/golang | Go 固有 |
出力形式
semgrep --config p/security-audit --sarif -o results.sarif . # SARIF
semgrep --config p/security-audit --json -o results.json . # JSON
特定のパスのスキャン
semgrep --config p/python app.py # Single file
semgrep --config p/javascript src/ # Directory
semgrep --config auto --include='**/test/**' . # Include tests
設定
.semgrepignore
tests/fixtures/
**/testdata/
generated/
vendor/
node_modules/
誤検知の抑制
password = get_from_vault() # nosemgrep: hardcoded-password
dangerous_but_safe() # nosemgrep
パート 2:カスタムルールの作成
カスタムルールを作成する場面
- プロジェクト固有の脆弱性パターンの検出
- 社内コーディング規約の徹底
- カスタムフレームワーク向けのセキュリティチェックの構築
- データフロー解析用の taint モードルールの作成
アプローチの選択
| アプローチ | 使用する場面 |
|---|---|
| Taint モード | 信頼できないソースから危険なシンクへのデータフローがある場合(インジェクション脆弱性) |
| パターンマッチング | データフロー要件のない構文パターン(非推奨 API、ハードコードされた値) |
インジェクション脆弱性には、taint モードを優先してください。パターンマッチングだけでは、eval(user_input)(脆弱)と eval("safe_literal")(安全)を区別できません。
クイックスタート:パターンマッチング
rules:
- id: hardcoded-password
languages: [python]
message: "Hardcoded password detected: $PASSWORD"
severity: ERROR
pattern: password = "$PASSWORD"
クイックスタート:Taint モード
rules:
- id: command-injection
languages: [python]
message: User input flows to command execution
severity: ERROR
mode: taint
pattern-sources:
- pattern: request.args.get(...)
- pattern: request.form[...]
pattern-sinks:
- pattern: os.system(...)
- pattern: subprocess.call($CMD, shell=True, ...)
pattern-sanitizers:
- pattern: shlex.quote(...)
パターン構文のクイックリファレンス
| 構文 | 説明 | 例 |
|---|---|---|
... | 任意のものにマッチ | func(...) |
$VAR | メタ変数をキャプチャ | $FUNC($INPUT) |
<... ...> | 式の深い部分にマッチ | <... user_input ...> |
| 演算子 | 説明 |
|---|---|
pattern | 完全一致するパターンにマッチ |
patterns | すべてにマッチ(AND) |
pattern-either | いずれかにマッチ(OR) |
pattern-not | マッチを除外 |
pattern-inside | コンテキスト内に限ってマッチ |
pattern-not-inside | コンテキスト外に限ってマッチ |
metavariable-regex | キャプチャした値に正規表現を適用 |
ルールのテスト
テストファーストは必須です。 注釈付きのテストファイルを作成してください。
# test_rule.py
def test_vulnerable():
user_input = request.args.get("id")
# ruleid: my-rule-id
cursor.execute("SELECT * FROM users WHERE id = " + user_input)
def test_safe():
user_input = request.args.get("id")
# ok: my-rule-id
cursor.execute("SELECT * FROM users WHERE id = ?", (user_input,))
テストを実行します。
semgrep --test --config rule.yaml test-file
コマンドリファレンス
| タスク | コマンド |
|---|---|
| テストの実行 | semgrep --test --config rule.yaml test-file |
| YAML の検証 | semgrep --validate --config rule.yaml |
| AST の出力 | semgrep --dump-ast -l <lang> <file> |
| Taint フローのデバッグ | semgrep --dataflow-traces -f rule.yaml file |
ルール作成のワークフロー
- 問題を分析する - バグのパターンを理解し、汚染追跡とパターンのどちらのアプローチを使うか判断します
- まずテストケースを作成する - ルールを書く前に、
ruleid:とok:のアノテーションを記述します - AST を分析する -
semgrep --dump-astを実行して、コードの構造を把握します - ルールを書く - シンプルに始めて、反復しながら改善します
- 100% 合格するまでテストする - 「見逃した行」や「誤った行」がない状態にします
- パターンを最適化する - テストに合格してから、冗長な部分だけを削除します
出力構造:
<rule-id>/
├── <rule-id>.yaml # Semgrep rule
└── <rule-id>.<ext> # Test file
詳細なリファレンス
公式 Semgrep ドキュメント:
ローカルのリファレンス:
- ワークフローガイド - ルール作成の手順を段階ごとに詳しく解説
- クイックリファレンス - パターン演算子と汚染追跡の構成要素
避けるべきアンチパターン
範囲が広すぎる場合:
# BAD: Matches any function call
pattern: $FUNC(...)
# GOOD: Specific dangerous function
pattern: eval(...)
安全なケースが不足している場合:
# BAD: Only tests vulnerable case
# ruleid: my-rule
dangerous(user_input)
# GOOD: Include safe cases
# ruleid: my-rule
dangerous(user_input)
# ok: my-rule
dangerous(sanitize(user_input))
退けるべき合理化
| 安易な考え方 | それが誤りである理由 |
|---|---|
| 「Semgrep が何も検出しなかったので、コードは安全だ」 | Semgrep はパターンベースのため、複雑な関数間のデータフローを追跡できません |
| 「パターンは完全に見える」 | テストされていないルールには、隠れた誤検出や見逃しがあります |
| 「脆弱なケースにマッチする」 | 脆弱性にマッチするのは作業の半分です。安全なケースにマッチしないことも確認してください |
| 「汚染追跡モードは大げさだ」 | インジェクションの脆弱性では、汚染追跡モードを使うと精度が向上します |
| 「テストケースは 1 つで十分だ」 | コーディングスタイルの違い、サニタイズ済みの入力、安全な代替手段など、エッジケースも含めてください |
CI/CD 統合
GitHub Actions
name: Semgrep
on:
push:
branches: [main]
pull_request:
schedule:
- cron: '0 0 1 * *'
jobs:
semgrep:
runs-on: ubuntu-latest
container:
image: returntocorp/semgrep
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Run Semgrep
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
semgrep ci --baseline-commit ${{ github.event.pull_request.base.sha }}
else
semgrep ci
fi
env:
SEMGREP_RULES: >-
p/security-audit
p/owasp-top-ten
p/trailofbits
リソース
ルールの作成:
- ルール構文:https://semgrep.dev/docs/writing-rules/rule-syntax
- パターン構文:https://semgrep.dev/docs/writing-rules/pattern-syntax
- ルールスキーマ:https://github.com/semgrep/semgrep-interfaces/blob/main/rule_schema_v1.yaml
一般:
- レジストリ:https://semgrep.dev/explore
- プレイグラウンド:https://semgrep.dev/playground
- ドキュメント:https://semgrep.dev/docs/
- Trail of Bits のルール:https://github.com/trailofbits/semgrep-rules
コメント
Markdown 対応