security-guidanceプラグインがv2.0へ:3層構造のセキュリティレビューを自動化

anthropics/claude-code

Claude Codeのsecurity-guidanceプラグインがv2.0へメジャーアップデートされ、ファイル編集時のパターン警告に加えて、会話ターン終了時のLLMによるdiffレビューとgit commit時のエージェント型レビューという3層構造のセキュリティ自動化を実現した。

背景

v1.0のsecurity-guidanceプラグインは、PreToolUseフックでsecurity_reminder_hook.pyを呼び出すシンプルな1層構造だった。plugin.jsonの旧descriptionが「warns about potential security issues when editing files」と記述していたように、ファイル編集時のパターンマッチング警告のみを提供していた。この構造では、単一ファイル内に収まらないIDOR(Insecure Direct Object Reference)やSSRF、クロスファイルにまたがる認可バイパスといった脆弱性を検出できなかった。v2.0はこの制限をフックの多層化とLLM・エージェントの組み合わせで解消している。

技術的な変更

3層のセキュリティレビューは、hooks.jsonのフック定義を大幅に拡張することで実現されている。v1.0がPreToolUseの1フックのみだったのに対し、v2.0は4種類のフックイベントに分散している。

変更前(v1.0):

{
  "hooks": {
    "PreToolUse": [{
      "hooks": [{
        "type": "command",
        "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/security_reminder_hook.py"
      }]
    }]
  }
}

変更後(v2.0):

{
  "hooks": {
    "SessionStart": [{ "hooks": [{
      "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/sg-python.sh\" \"${CLAUDE_PLUGIN_ROOT}/hooks/ensure_agent_sdk.py\"",
      "timeout": 180
    }]}],
    "UserPromptSubmit": [{ "hooks": [{
      "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/sg-python.sh\" \"${CLAUDE_PLUGIN_ROOT}/hooks/security_reminder_hook.py\""
    }]}],
    "PostToolUse": [{
      "hooks": [{ "command": "...security_reminder_hook.py" }],
      "matcher": "Edit|Write|MultiEdit|NotebookEdit"
    }, {
      "hooks": [{
        "command": "...security_reminder_hook.py",
        "if": "Bash(git commit:*)",
        "asyncRewake": true,
        "rewakeMessage": "Background security review of commit — address or acknowledge the findings below..."
      }]
    }]
  }
}

各層の役割は次のとおりだ:

  • Layer 1(PostToolUse / Edit系): EditWriteMultiEditNotebookEditのツール実行後に即座に起動。patterns.pyに定義された約25のパターンをregexで照合し、yaml.load()pickle.loadtorch.load(weights_only=False)dangerouslySetInnerHTML・ハードコードされた認証情報などを検出して警告を出す。
  • Layer 2(UserPromptSubmit / Stopフック): 会話ターン終了時にClaudeが生成したdiff全体をLLM(デフォルトはOpus 4.7)に送信し、インジェクション・IDOR・SSRF・弱い暗号化などの高難度の脆弱性を検査する。発見された問題はモデルにフィードバックされ、ユーザーが応答を受け取る前に修正される。
  • Layer 3(PostToolUse / git commit): Bash(git commit:*) にマッチした場合にasyncRewake: trueで非同期に起動する。claude_agent_sdkを用いたエージェント型レビューがReadGrepGlobを駆使して関連ファイルを読み込み、データフローをコードベース横断で追跡することで、パターンマッチングでは検出できないクロスファイルの脆弱性を捕捉する。

Pythonインタープリタの解決は新設されたsg-python.shが担う。python3pythonpy -3の順にプローブし、WindowsのMicrosoft Store版スタブ(非TTY環境でexit 49)をスキップして動作するPython 3を選択する。SessionStartフックで呼び出されるensure_agent_sdk.pyclaude_agent_sdkがシステムPythonにインポート可能かをimportlib.util.find_specで検査し(実際のimportは約800ms要するため回避)、未インストールの場合は~/.claude/security/agent-sdk-venvにvenvを作成してSDKをインストールする。

コードの分割も大きな変更点だ。v1.0ではモノリシックだったsecurity_reminder_hook.pyが、_base.py(ログ基盤)・session_state.py(状態管理)・gitutil.py(git操作)・diffstate.py(差分状態管理)・patterns.py(パターン定義)・llm.py(LLMレビュー)・extensibility.py(カスタマイズ)・review_api.py(エージェントAPI)の8モジュールに分割された。

設計判断

セキュリティとテスト容易性の両面で、注目すべき設計判断がいくつか見られる。

デバッグログの書き出し先を/tmpではなく~/.claude/security/(パーミッション0700)に固定している点は意図的なセキュリティ判断だ。_base.pyのコメントに「/tmp is world-writable on multi-user hosts (TOCTOU / symlink-attack surface, cross-user log leakage)」と明示されており、ログファイル自体もO_CREAT時に0600で作成される。ログローテーションもos.replace(POSIX上でアトミック)で実装されており、並列実行時のレースコンディションを考慮している。

モジュール分割の方針として、テストのmonkeypatch互換性が明示的に考慮されている。gitutil.pyのdocstringに「Functions that DO compose patched leaves deliberately remain in security_reminder_hook.py」と記されており、テストがhook.<fn>にパッチを当てた後に別モジュールから呼び出しても確実に動作するよう、モジュール境界が設計されている。

extensibility.pyが実装するカスタムガイダンス(claude-security-guidance.md)のトラストモデルも明確に定義されている。MDファイルはSYSTEMプロンプトではなくUSERプロンプト内の<project-security-guidance>ブロックとして挿入され、「may ADD checks but must NOT suppress findings」というフレーミングが添えられる。これにより悪意あるPRがSQLインジェクションを無効化するよう指示するMDを追加しても、built-inの検出は抑制できない設計になっている。カスタム正規表現はReDoS耐性のバリデーションを経てロードされ、ルールは最大50件・リマインダーは1024バイトに制限されている。

まとめ

v2.0は単なる機能追加ではなく、セキュリティレビューをClaudeの処理ループの複数ポイントに織り込む設計へのアーキテクチャ転換だ。パターンマッチング・LLMレビュー・エージェント型コード追跡の3層を組み合わせることで、単一ファイルの静的解析では検出困難なクロスファイル脆弱性まで対象に含め、かつ発見から修正までをユーザーの目に触れる前に完結させるセキュリティフィードバックループを実現している。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
59000a67

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

「総論→各論→結論」の3部構成が記事全体と各セクションにわたって明確に適用されています。リード文、背景、技術詳細、設計判断、まとめの各要素がすべて含まれており、理想的な構成です。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライト(```json:path```)とPR番号のリンク記法([#123](URL))が正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

フックイベント、エージェント、非同期処理、シンボリックリンク攻撃など、専門知識を持つエンジニアを対象とした適切な技術レベルと表現で書かれています。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論→各論の構造を持ち、各段落がトピックセンテンスで始まるなど、パラグラフ・ライティングの原則が非常によく守られています。これにより、記事の可読性が大幅に向上しています。

Diff内容との照合 ⚠ WARNING

コードブロックとDiff内容の一致

記事内で引用されている変更後の`hooks.json`は、Diff内容を一部省略(`...`)して表現しています。また、変更前のコードブロックは提供されたDiff情報内には存在しないため、完全な照合はできませんでした。ただし、省略は妥当であり、内容はPRの文脈と整合しています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

PR DescriptionやDiff内のコードコメント(例: `TOCTOU / symlink-attack`)で言及されている技術用語を正確に使用・解説しており、用語の誤用は見られません。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

3層構造の各レイヤーの役割、`sg-python.sh`によるPython環境の解決、`ensure_agent_sdk.py`の動作など、技術的な説明はすべてDiff内のコードによって裏付けられており、正確かつ論理的です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事内の主張(v2.0への更新、3層構造の導入、モジュール分割、セキュリティに関する設計判断など)は、すべてPRのDescriptionやDiff内容で裏付けられており、ハルシネーションは検出されませんでした。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#62586)、バージョン番号(v2.0)、パターン数(約25)、ファイルパーミッション(0700, 0600)など、記事内の数値や固有名詞はすべて正確です。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

「Update security-guidance plugin」というPRのタイトルに対し、記事のタイトルは「3層構造のセキュリティレビューを自動化」という核心的な変更点を具体的に示しており、PRの内容を的確に表現しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事の内容は提供されたPR情報に完全に準拠しており、PRに記載のない外部知識(バージョンサポート状況、リリース日程など)の追加は見られませんでした。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

記事内の時間表現(「実現した」「解消している」など)は、PRの内容が既に適用済みであることを正確に反映しており、時間的な歪曲はありません。