commit-security-scan について
commit-security-scanは、コード変更を調べるセキュリティレビュー用スキルです。リポジトリの脅威モデルを基にSTRIDEの観点で評価し、検出結果をJSONレポートにまとめます。
主な機能
- 01コミット、PR、差分のスキャン
- 02STRIDEに沿った脆弱性確認
- 03リポジトリの脅威モデルの利用
- 04深刻度と確信度の評価
- 05JSON形式の検出レポート生成
活用シーン
- 01PRのセキュリティリスク確認
- 02コミット前のステージ済み変更の検査
- 03ブランチやコミット範囲の比較
- 04直近のコミットの脆弱性確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ factory-ai/ factory-plugins --skill commit-security-scanインストール後、Claude Code で/commit-security-scanを入力して読み込まれたか確認します。
同梱ファイルanalysis-examples.md
詳細
コミットのセキュリティスキャン
LLM を活用した推論により、コードの変更(コミット、PR、差分)を分析し、セキュリティ脆弱性を検出します。このスキルはコードを直接読み取り、リポジトリの脅威モデルに基づくパターンを適用して、STRIDE のすべてのカテゴリにわたる問題を特定します。
このスキルを使用するタイミング
- PR レビュー - プルリクエストの自動セキュリティスキャン
- コミット前チェック - コミット前にステージされた変更をスキャン
- ブランチの比較 - フィーチャーブランチの変更のセキュリティを確認
- コードレビューの支援 - レビュアーがセキュリティ上の問題を見つけるのを支援
前提条件
このスキルには、次のものが必要です。
- 脅威モデル -
.factory/threat-model.mdが存在すること - セキュリティ設定 - 重大度のしきい値を定める
.factory/security-config.json
重要:これらのファイルが存在しない場合、セキュリティスキャンを開始する前に、必ず生成してください。
前提条件を生成するには、次の手順を実行します。
- ユーザーに「脅威モデルがまだありません。スキャンを開始する前に生成します。」と伝えます。
threat-model-generationスキルを実行し、両方のファイルを作成します。- 完了したら、セキュリティスキャンを続行します。
ユーザーに手動でスキルを実行するよう求めないでください。このワークフローの一環として、自動的に実行してください。
入力
スキャン対象は、ユーザーのリクエストに基づいて決定します。
| スキャンの種類 | 指定方法 | 例 |
|---|---|---|
| PR | 「PR #123 をスキャン」 | セキュリティ脆弱性について PR #456 をスキャン |
| コミット範囲 | 「コミット X..Y をスキャン」 | コミット abc123..def456 をスキャン |
| 単一コミット | 「コミット X をスキャン」 | コミット abc123 をスキャン |
| ステージされた変更 | 「ステージされた変更をスキャン」 | ステージされた変更にセキュリティ上の問題がないかスキャン |
| 未コミットの変更 | 「未コミットの変更をスキャン」 | 作業ディレクトリの変更をスキャン |
| ブランチの比較 | 「X から Y までをスキャン」 | main から feature-branch への変更をスキャン |
| 直近 N 件のコミット | 「直近 N 件のコミットをスキャン」 | 直近 3 件のコミットをスキャン |
範囲が指定されていない場合は、ユーザーに確認を求めます。
手順
次の手順を順番に実行してください。
ステップ 1:前提条件を確認する(不足している場合は自動生成)
次のファイルを読み取ってみます。
.factory/threat-model.md.factory/security-config.json
いずれかのファイルが存在しない、または読み取れない場合:
- ユーザーに「セキュリティ脅威モデルがまだありません。まず生成します。少し時間がかかる場合があります。」と伝えます。
threat-model-generationスキルを呼び出してリポジトリを分析し、両方のファイルを作成します。- 生成が完了したら、ステップ 2 に進みます。
これにより、正確な分析に必要な脅威モデルの情報を常に利用できる状態で、セキュリティスキャンを実施できます。
ステップ 2:変更されたファイルを取得する
ユーザーのリクエストに基づいて、git を使用し、変更されたファイルの一覧と差分を取得します。
- PR の場合:
gh pr diffを使用します - コミット/範囲の場合:
git diffまたはgit showを使用します - ステージされた変更の場合:
git diff --cachedを使用します
各変更ファイルの全内容を読み取り、コンテキストを把握します。
ステップ 3:脅威モデルを読み込む
.factory/threat-model.md と .factory/security-config.json を読み取り、次の内容を把握します。
- システムのアーキテクチャと信頼境界
- このコードベースで既知の脆弱性パターン
- 検出事項の重大度のしきい値
ステップ 4:脆弱性を分析する
変更された各ファイルについて、STRIDE の脅威を体系的に確認します。
S - なりすまし(Spoofing Identity)
- 認証チェックの欠落または不備
- セッション処理の脆弱性
- コード内でのトークン/認証情報の露出
- 安全でない Cookie 設定
T - データの改ざん(Tampering with Data)
- SQL インジェクション:SQL クエリでの文字列連結/補間
- コマンドインジェクション:シェルコマンド、
eval()、exec()でのユーザー入力の使用 - XSS:HTML/テンプレート内でのユーザー入力の未エスケープ
- マスアサインメント:リクエストからモデルへの無検証な代入
- パストラバーサル:検証されていないユーザー入力をファイルパスに使用
R - 否認
- 機密性の高い操作に対する監査ログがありません
- エラーログが不十分です
- ログインジェクションの脆弱性があります
I - 情報漏えい
- IDOR:所有権の確認を行わずにオブジェクトへ直接アクセスできます
- 内部情報を露呈する詳細なエラーメッセージ
- ハードコードされたシークレット、API キー、認証情報
- ログやレスポンスに含まれる機密データ
- デバッグ用エンドポイントが公開されています
D - サービス拒否
- エンドポイントにレート制限がありません
- リソース消費に上限がありません(ファイルアップロード、クエリ)
- アルゴリズムの計算量を悪用する攻撃(正規表現、ソート)
- 一覧表示エンドポイントにページネーションがありません
E - 権限昇格
- エンドポイントに認可チェックがありません
- ロールや権限を回避できる可能性があります
- パラメーター操作による権限昇格
ステップ 5:各検出事項を評価する
脆弱性の可能性がある項目ごとに、次の手順を実施します。
-
データフローを追跡する:ユーザー入力の送信元から到達先まで追跡します
- 入力元はどこですか?(リクエストパラメーター、本文、ヘッダー、ファイル)
- 検証やサニタイズを経由していますか?
- 最終的にどこへ渡されますか?(データベース、シェル、レスポンス、ファイルシステム)
-
既存の緩和策を確認する:
- コードベース内の別の場所で検証されていますか?
- このコードを保護するミドルウェアやデコレーターはありますか?
- フレームワークによる自動保護はありますか?
-
深刻度を判定する:
- CRITICAL:リモートコード実行、認証の回避、データ侵害
- HIGH:SQL インジェクション、XSS、IDOR、権限昇格
- MEDIUM:情報漏えい、セキュリティヘッダーの欠如
- LOW:ベストプラクティス違反、軽微な問題
-
確信度を評価する:
- HIGH:明確な脆弱パターン、直接的なデータフロー、緩和策なし
- MEDIUM:脆弱性の可能性はあるが、コンテキストに不確実性がある
- LOW:疑わしいパターンだが、確認できない緩和策が適用されている可能性が高い
ステップ 6:レポートを生成する
次の構造で security-findings.json を作成します。
{
"scan_id": "scan-YYYY-MM-DD-XXX",
"scan_date": "<ISO 8601 timestamp>",
"scan_type": "pr|commit|range|staged|working",
"commit_range": "<base>..<head>",
"pr_number": null,
"threat_model_version": "<from security-config.json>",
"findings": [
{
"id": "VULN-001",
"severity": "HIGH",
"stride_category": "Tampering",
"vulnerability_type": "SQL Injection",
"cwe": "CWE-89",
"file": "src/api/users.py",
"line_range": "45-49",
"code_context": "<vulnerable code snippet>",
"analysis": "<explanation of why this is vulnerable>",
"exploit_scenario": "<how an attacker could exploit this>",
"threat_model_reference": "Section 5.2 - SQL Injection",
"existing_mitigations": [],
"recommended_fix": "<how to fix the vulnerability>",
"confidence": "HIGH",
"reasoning": "<why this confidence level>"
}
],
"summary": {
"total_findings": 0,
"by_severity": { "CRITICAL": 0, "HIGH": 0, "MEDIUM": 0, "LOW": 0 },
"by_stride": {
"Spoofing": 0,
"Tampering": 0,
"Repudiation": 0,
"InfoDisclosure": 0,
"DoS": 0,
"ElevationOfPrivilege": 0
},
"files_analyzed": 0
}
}
ステップ 7:結果を報告する
- 検出事項を
security-findings.jsonに保存します - 概要をユーザーに報告します(深刻度別の検出数、しきい値の超過状況)
security-config.jsonの深刻度しきい値を確認し、超過しているものがあれば記載します
CWE リファレンス
検出事項によく使われる CWE のマッピング:
| 脆弱性の種類 | CWE |
|---|---|
| SQL インジェクション | CWE-89 |
| コマンドインジェクション | CWE-78 |
| XSS(反射型) | CWE-79 |
| XSS(格納型) | CWE-79 |
| パストラバーサル | CWE-22 |
| IDOR | CWE-639 |
| 認証の欠如 | CWE-306 |
| 認可の欠如 | CWE-862 |
| ハードコードされた認証情報 | CWE-798 |
| 機密データの露出 | CWE-200 |
| マスアサインメント | CWE-915 |
| オープンリダイレクト | CWE-601 |
| SSRF | CWE-918 |
| XXE | CWE-611 |
| 安全でないデシリアライズ | CWE-502 |
呼び出し例
PR をスキャンする:
Scan PR #123 for security vulnerabilities
コミット前にステージ済みの変更をスキャンする:
Scan my staged changes for security issues
フィーチャーブランチをスキャンする:
Scan changes from main to feature/user-auth for vulnerabilities
最近のコミットをスキャンする:
Scan the last 5 commits for security issues
参考資料
- 分析例:
analysis-examples.md(このスキルディレクトリ内) - 脅威モデル:
.factory/threat-model.md - セキュリティ設定:
.factory/security-config.json - OWASP Top 10
- CWE Top 25