mcpField
Z
zeroize-audit

zeroize-audit

github.com/trailofbitsセキュリティ7.9k4.8k 回インストール今日更新
リポジトリ

zeroize-audit について

C、C++、Rust のコードを対象に、機密データのゼロ化漏れやコンパイラー最適化による削除を調べるセキュリティ監査スキルです。ソースとデータフローの分析に LLVM IR・アセンブリの証拠を組み合わせ、構造化レポートを作成します。

主な機能

  1. 01機密データのゼロ化監査
  2. 02C、C++、Rust の分析
  3. 03LLVM IR とアセンブリの検査
  4. 04秘密データコピーの追跡
  5. 05PoC とレポートの生成

活用シーン

  1. 01暗号鍵の消去監査
  2. 02パスワードやトークン処理の確認
  3. 03ゼロ化処理の最適化後検証
  4. 04機密データを扱うエラーパスの確認

MCP 対応

Serena MCP によるセマンティッククエリを利用できます。設定により MCP の無効化、優先利用、必須化を選べます。

インストール

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

$npx skills add https://github.com/trailofbits/skills --skill zeroize-audit

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

同梱ファイル

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

agents/
openai.yaml
assets/
trail-of-bits-mark.svg
configs/
c.yaml
default.yaml
rust.yaml
prompts/
report_template.md
system.md
task.md
references/
compile-commands.md
detection-strategy.md
ir-analysis.md
mcp-analysis.md
poc-generation.md
rust-zeroization-patterns.md
schemas/
input.json
output.json
tools/
analyze_asm.sh
analyze_cfg.py
analyze_heap.sh
analyze_ir_semantic.py
diff_ir.sh
diff_rust_mir.sh
emit_asm.sh
emit_ir.sh
emit_rust_asm.sh
emit_rust_ir.sh
emit_rust_mir.sh
extract_compile_flags.py
generate_poc.py
tools/mcp/
apply_confidence_gates.py

詳細

zeroize-audit

使用する場面

  • 暗号実装(鍵、シード、ノンス、秘密情報)を監査する場合
  • 認証システム(パスワード、トークン、セッションデータ)をレビューする場合
  • PII や機密性の高い認証情報を扱うコードを分析する場合
  • セキュリティが重要なコードベースで、安全なクリーンアップを検証する場合
  • 機密データの取り扱いに関するメモリ安全性を調査する場合

使用しない場面

  • セキュリティに重点を置かない一般的なコードレビュー
  • パフォーマンスの最適化(安全な消去に関連する場合を除く)
  • 機密データに関係しないリファクタリング作業
  • 特定可能な秘密情報や機密値を含まないコード

実行契約

ファイルアクセス、シェルコマンド、ワーカーの実行、ユーザー入力に利用できるエージェント環境のツールを使用してください。allowed-tools エントリとロールファイルのフロントマターは、以前のホストメタデータです。他の環境のツール名を定義したり、その環境で権限を付与したりするものではありません。

  • リソースを解決します。 baseDir を SKILL.md が格納されている絶対ディレクトリに設定します。リンク先の 入力スキーマ と オーケストレータープロンプト がそこに存在することを確認します。{baseDir}、{workdir}、{{input}} はオーケストレーターが置換する値を示す表記であり、環境変数でも、自動的に展開されるものでもありません。相対 Markdown リンクは、それを含むファイルのディレクトリを基準に解決し、{baseDir}/… パスはスキルのディレクトリを基準に解決します。解決したパスをワーカーとシェルコマンドに渡します。
  • ロールを起動します。 Agent Architecture テーブルにリンクされたロールプロンプトを読みます。環境にそのロールの登録済みワーカーがある場合は、zeroize-audit:<role-name> 識別子(例:zeroize-audit:0-preflight)を使用します。ない場合は、そのプロンプトの Markdown 本文、現在のフェーズの指示、パラメーター値を使って独立したワーカーを作成します。フェーズのテーブルに記載がない場合も含め、解決済みの baseDir と、作成後は workdir を必ず含めます。委任する前に、上記の規則に従ってリソース参照を解決します。ワーカーによるファイル操作、検索、シェル操作には、環境で実際に利用できるツールのスキーマと権限を使用します。ロール名は指示を識別するものであり、特定のディスパッチ API やモデルを必須とするものではありません。
  • 結果を待ちます。 各ワーカーのハンドルを保持し、環境の完了通知手段を使って結果を待ちます。起動の確認通知は完了を意味しません。完了状態を更新したり依存するフェーズを開始したりする前に、そのフェーズで必要な成果物を読みます。ワーカーの失敗時またはディスパッチを利用できない場合は、そのフェーズに記載されたフォールバックのみを適用します。それ以外の場合は、既存の実行状態に失敗を記録し、該当フェーズをブロック中として報告します。
  • 並行処理。 利用可能な並行数とフェーズ間のバリアを守ります。並列実行ができない場合は、ワーカーを順次実行します。TU ごとのコンパイラーワーカーは別々のディレクトリに書き込むため、並行して実行できます。
  • 判断を収集します。 環境のユーザー入力機能を使うか、会話内で質問します。フェーズで回答が必要な場合は回答を待ち、デフォルト値や経過時間でユーザーの判断を代替しないでください。PoC の結果を受け入れる場合も却下する場合も、記録時に検証および確認の結果を保持します。

実行方法

「このクレートにメモリ上に残されたシークレットがないか監査して」や「この C ライブラリが実際にキーを消去しているか確認して」といったリクエストの場合:

  1. 入力を収集します。 リクエストの内容を以下の Inputs テーブルに対応付けます(完全なスキーマ:schemas/input.json)。path は必須で、さらに compile_db(C/C++)または cargo_manifest(Rust)の少なくとも一方が必要です。どちらも指定されておらず、リポジトリからも特定できない場合は、ユーザーに確認してください。どちらもないと、事前チェックで実行が停止します。ユーザーから別の指示がない限り、ほかのフィールドはすべてデフォルトのままにします。
  2. オーケストレータープロンプトを読み、収集した入力をその {{placeholder}} 値に代入します。そこに記述されたオーケストレーターとして動作してください。このプロンプトでは、状態の復旧、フェーズループ、早期終了、エラー処理を定義しています。各フェーズが依存する共通の作業ディレクトリ構成とエージェントのエラープロトコルについては、共有指示も合わせて読んでください。
  3. フェーズループを実行します。 フェーズ 0~7 を順番に実行します。各フェーズの前に、{baseDir}/workflows/phase-{N}-{name}.md からそのフェーズのワークフローファイルを読み、前提条件、指示、状態更新、エラー処理の各セクションに従ってください。各ワークフローには、上記の実行契約に基づいて使用する役割プロンプトとパラメーターが指定されています。フェーズごとのスキップ条件と、task.md に記載された早期終了ルールを守ってください。
  4. レポートを返します(フェーズ 8、インライン)。{workdir}/report/final-report.md を読み、その内容をスキルの出力として返してください。

中断した実行を再開するには、以前のコンテキストから workdir が分かる場合、{workdir}/orchestrator-state.json を読み、フェーズ 0 からではなく current_phase から続行してください(task.md の復旧セクションを参照)。


目的

ソースコード内の機密データのゼロ化漏れを検出し、コンパイラーの最適化(デッドストア削除など)によってゼロ化が削除または弱体化されていないかを、必須の LLVM IR/アセンブリの証拠とともに特定します。次の機能があります。

  • レジスタスピルとスタック上への残留に関するアセンブリレベルの分析
  • シークレットのコピーのデータフロー追跡
  • ヒープアロケーターのセキュリティ警告
  • ループ展開と SSA 形式のセマンティック IR 分析
  • パスカバレッジ検証のための制御フローグラフ分析
  • ランタイム検証テストの生成

対象範囲

  • 対象コードベースに対して読み取り専用です(監査対象のコードは変更せず、一時作業ディレクトリに分析アーティファクトを書き込みます)。
  • 構造化レポート(JSON)を生成します。
  • 有効なビルドコンテキスト(compile_commands.json)と、コンパイル可能な翻訳単位が必要です。
  • 「最適化による削除」という指摘は、コンパイラーの証拠(IR/アセンブリの差分)がある場合に限り許可されます。

入力

完全なスキーマについては、schemas/input.json を参照してください。主なフィールドは次のとおりです。

フィールド必須デフォルト説明
pathはい—リポジトリのルート
compile_dbいいえnullC/C++ の解析に使用する compile_commands.json のパスです。cargo_manifest が設定されていない場合は必須です。
cargo_manifestいいえnullRust クレートの解析に使用する Cargo.toml のパスです。compile_db が設定されていない場合は必須です。
configいいえ—ヒューリスティックと承認済みのワイプを定義する YAML
opt_levelsいいえ["O0","O1","O2"]IR 比較に使用する最適化レベルです。O1 は診断レベルです。ワイプが O1 で消える場合は単純な DSE であり、O2 ではより積極的な除去が検出されます。
languagesいいえ["c","cpp","rust"]解析する言語
max_tusいいえ50compile DB から処理する翻訳単位の上限
mcp_modeいいえpreferoff、prefer、または require のいずれかで、Serena MCP の使用を制御します
mcp_required_for_advancedいいえtrueMCP が利用できない場合、SECRET_COPY、MISSING_ON_ERROR_PATH、NOT_DOMINATING_EXITS を needs_review に格下げします
mcp_timeout_msいいえ10000MCP のセマンティッククエリに割り当てるタイムアウト時間
poc_categoriesいいえ悪用可能な 11 カテゴリすべてPoC を生成する検出カテゴリです。C/C++ の検出結果では 11 カテゴリすべてがサポートされます。Rust の検出結果では MISSING_SOURCE_ZEROIZE、SECRET_COPY、PARTIAL_WIPE のみがサポートされ、その他の Rust カテゴリは poc_supported=false としてマークされます。
poc_output_dirいいえgenerated_pocs/生成された PoC の出力ディレクトリ
enable_asmいいえtrueアセンブリの出力と解析(ステップ 8)を有効にします。STACK_RETENTION、REGISTER_SPILL を生成します。emit_asm.sh が見つからない場合は自動的に無効になります。
enable_semantic_irいいえfalseLLVM IR のセマンティック解析(ステップ 9)を有効にします。LOOP_UNROLLED_INCOMPLETE を生成します。
enable_cfgいいえfalse制御フローグラフの解析(ステップ 10)を有効にします。MISSING_ON_ERROR_PATH、NOT_DOMINATING_EXITS を生成します。
enable_runtime_testsいいえfalseランタイムテストハーネスの生成(ステップ 11)を有効にします。

前提条件

実行前に、以下を確認してください。それぞれに定義済みの失敗時の動作があります。

C/C++ の前提条件:

前提条件不足している場合の動作
compile_db パスにある compile_commands.json即時に失敗し、処理を続行しません
PATH 上の clang即時に失敗します — IR/ASM の分析ができません
PATH 上の uvx(Serena 用)mcp_mode=require の場合:失敗します。mcp_mode=prefer の場合:MCP なしで続行し、信頼度ゲーティングのルールに従って該当する検出結果の信頼度を下げます。
{baseDir}/tools/extract_compile_flags.py即時に失敗します — TU ごとのフラグを抽出できません
{baseDir}/tools/emit_ir.sh即時に失敗します — IR 分析ができません
{baseDir}/tools/emit_asm.sh警告してアセンブリに関する検出結果をスキップします(STACK_RETENTION、REGISTER_SPILL)
{baseDir}/tools/mcp/check_mcp.sh警告して MCP を利用できないものとして扱います
{baseDir}/tools/mcp/normalize_mcp_evidence.py警告して MCP の生出力を使用します

Rust の前提条件:

前提条件不足している場合の動作
cargo_manifest パスにある Cargo.toml即時に失敗し、処理を続行しません
cargo check が成功すること即時に失敗します — クレートをビルド可能な状態にする必要があります
PATH 上の cargo +nightly即時に失敗します — MIR と LLVM IR の出力には nightly が必要です
PATH 上の uv即時に失敗します — Python 分析スクリプトの実行に必要です
{baseDir}/tools/validate_rust_toolchain.sh警告します — 事前チェックを手動で実行してください。すべてのツール、スクリプト、nightly、および任意で cargo check を確認します。機械可読な出力には --json を、クレートのビルド検証も行うには --manifest を使用します。
{baseDir}/tools/emit_rust_mir.sh即時に失敗します — MIR 分析ができません(--opt、--crate、--bin/--lib に対応。--out にはファイルまたはディレクトリを指定できます)
{baseDir}/tools/emit_rust_ir.sh即時に失敗します — LLVM IR 分析ができません(--opt が必須。--crate、--bin/--lib に対応。--out には .ll を指定する必要があります)
{baseDir}/tools/emit_rust_asm.sh警告してアセンブリに関する検出結果をスキップします(STACK_RETENTION、REGISTER_SPILL)。--opt、--crate、--bin/--lib、--target、--intel-syntax に対応。--out には .s ファイルまたはディレクトリを指定できます。
{baseDir}/tools/diff_rust_mir.sh警告して MIR レベルの最適化比較をスキップします。2 つ以上の MIR ファイルを受け取り、正規化してペアごとに差分を取り、zeroize/drop-glue パターンが消失する最初の最適化レベルを報告します。
{baseDir}/tools/scripts/semantic_audit.py警告してセマンティックなソース分析をスキップします
{baseDir}/tools/scripts/find_dangerous_apis.py警告して危険な API のスキャンをスキップします
{baseDir}/tools/scripts/check_mir_patterns.py警告して MIR 分析をスキップします
{baseDir}/tools/scripts/check_llvm_patterns.py警告して LLVM IR 分析をスキップします
{baseDir}/tools/scripts/check_rust_asm.py警告して Rust アセンブリ分析をスキップします(STACK_RETENTION、REGISTER_SPILL、drop-glue のチェック)。check_rust_asm_x86.py(本番用)または check_rust_asm_aarch64.py(実験的 — AArch64 の検出結果は手動で検証する必要があります)に振り分けます。
{baseDir}/tools/scripts/check_rust_asm_x86.pyx86-64 分析で check_rust_asm.py が必要とします。不足している場合は警告してスキップします
{baseDir}/tools/scripts/check_rust_asm_aarch64.pyAArch64 分析で check_rust_asm.py が必要とします(実験的)。不足している場合は警告してスキップします

共通の前提条件:

前提条件不足している場合の動作
{baseDir}/tools/generate_poc.py即時に失敗します — PoC の生成は必須です

承認済みの消去 API

以下は、有効なゼロ化として認識されます。追加の項目は {baseDir}/configs/ で設定してください。

C/C++

  • explicit_bzero
  • memset_s
  • SecureZeroMemory
  • OPENSSL_cleanse
  • sodium_memzero
  • volatile な消去ループ(パターンベース。{baseDir}/configs/default.yaml の volatile_wipe_patterns を参照)
  • IR 内:volatile フラグ付きの llvm.memset、volatile なストア、または消去されない消去関数の呼び出し

Rust

  • zeroize::Zeroize トレイト(zeroize() メソッド)
  • Zeroizing<T> ラッパー(drop ベース)
  • ZeroizeOnDrop derive マクロ

検出結果の確認

検出結果は、必要な証拠ごとにグループ化されています。利用可能なツールで必要な証拠を確認できる検出結果のみを試してください。

検出結果 ID説明必要なものPoC の対応状況
MISSING_SOURCE_ZEROIZEソースコード内にゼロ化処理が見つからないソースコードのみ対応(C/C++ と Rust)
PARTIAL_WIPEサイズが正しくない、またはワイプが不完全ソースコードのみ対応(C/C++ と Rust)
NOT_ON_ALL_PATHS一部の制御フローパスでゼロ化が欠落している(ヒューリスティック)ソースコードのみ対応(C/C++ のみ)
SECRET_COPYゼロ化の追跡なしに機密データがコピーされているソースコード + MCP が望ましい対応(C/C++ と Rust)
INSECURE_HEAP_ALLOCシークレットに安全でないアロケーターを使用している(malloc と secure_malloc の比較)ソースコードのみ対応(C/C++ のみ)
OPTIMIZED_AWAY_ZEROIZEコンパイラーがゼロ化処理を削除したIR の差分が必要(ソースコードのみでは不可)対応
STACK_RETENTION関数の戻り後もスタックフレームにシークレットが残る可能性があるアセンブリが必要(C/C++);LLVM IR の alloca+lifetime.end の証拠(Rust);アセンブリによる裏付けがある場合は判定が「confirmed」に引き上げられる対応(C/C++ のみ)
REGISTER_SPILLレジスター内のシークレットがスタックにスピルされているアセンブリが必要(C/C++);LLVM IR の load+呼び出しサイトの証拠(Rust);アセンブリによる裏付けがある場合は判定が「confirmed」に引き上げられる対応(C/C++ のみ)
MISSING_ON_ERROR_PATHエラー処理のパスにクリーンアップがないCFG または MCP が必要対応
NOT_DOMINATING_EXITSワイプがすべての終了箇所を支配していないCFG または MCP が必要対応
LOOP_UNROLLED_INCOMPLETE展開されたループのワイプが不完全セマンティック IR が必要対応

エージェントアーキテクチャ

分析パイプラインでは、8つのフェーズにわたって11種類のワーカーロールを使用し、上記の実行コントラクトに従ってオーケストレーターが起動します。エージェントは共有作業ディレクトリ(/tmp/zeroize-audit-{run_id}/)に永続的な所見ファイルを書き込み、並列実行を可能にするとともに、コンテキストの逼迫を防ぎます。

エージェントフェーズ目的出力ディレクトリ
0-preflightPhase 0事前チェック(ツール、ツールチェーン、コンパイル DB、クレートのビルド)、設定のマージ、作業ディレクトリの作成、TU の列挙{workdir}/
1-mcp-resolverPhase 1, Wave 1(C/C++ のみ)Serena MCP を介してシンボル、型、ファイル間参照を解決mcp-evidence/
2-source-analyzerPhase 1, Wave 2a(C/C++ のみ)機密オブジェクトの特定、ワイプの検出、正確性の検証、データフロー/ヒープの分析source-analysis/
2b-rust-source-analyzerPhase 1, Wave 2b(Rust のみ、2a と並列)Rustdoc JSON によるトレイト対応分析+危険な API の grepsource-analysis/
3-tu-compiler-analyzerPhase 2, Wave 3(C/C++ のみ、N 並列)TU ごとの IR 差分、アセンブリ、セマンティック IR、CFG 分析compiler-analysis/{tu_hash}/
3b-rust-compiler-analyzerPhase 2, Wave 3R(Rust のみ、単一エージェント)クレートレベルの MIR、LLVM IR、アセンブリの分析rust-compiler-analysis/
4-report-assemblerPhase 3(中間)+ Phase 6(最終)すべてのエージェントから所見を収集し、信頼度ゲートを適用します。PoC の結果を統合し、最終レポートを作成しますreport/
5-poc-generatorPhase 4専用の概念実証プログラムを作成(C/C++:すべてのカテゴリ、Rust:MISSING_SOURCE_ZEROIZE、SECRET_COPY、PARTIAL_WIPE)poc/
5b-poc-validatorPhase 5すべての PoC をコンパイルして実行poc/
5c-poc-verifierPhase 5各 PoC が主張する所見を証明していることを検証poc/
6-test-generatorPhase 7(任意)実行時検証テストハーネスを生成tests/

オーケストレーターは、{baseDir}/workflows/からフェーズごとのワークフローファイルを一度に1つ読み込み、コンテキスト圧縮後に復旧できるようorchestrator-state.jsonを維持します。エージェントには、値ではなくファイルパス(config_path)で設定を渡します。

実行フロー
Phase 0: 0-preflight agent — Preflight + config + create workdir + enumerate TUs
           → writes orchestrator-state.json, merged-config.yaml, preflight.json
Phase 1: Wave 1:  1-mcp-resolver              (skip if mcp_mode=off OR language_mode=rust)
         Wave 2a: 2-source-analyzer           (C/C++ only; skip if no compile_db)  ─┐ parallel
         Wave 2b: 2b-rust-source-analyzer     (Rust only; skip if no cargo_manifest) ─┘
Phase 2: Wave 3:  3-tu-compiler-analyzer x N  (C/C++ only; parallel per TU)
         Wave 3R: 3b-rust-compiler-analyzer   (Rust only; single crate-level agent)
Phase 3: Wave 4:  4-report-assembler          (mode=interim → findings.json; reads all agent outputs)
Phase 4: Wave 5:  5-poc-generator             (C/C++: all categories; Rust: MISSING_SOURCE_ZEROIZE, SECRET_COPY, PARTIAL_WIPE; other Rust findings: poc_supported=false)
Phase 5: PoC Validation & Verification
           Step 1: 5b-poc-validator agent      (compile and run all PoCs)
           Step 2: 5c-poc-verifier agent       (verify each PoC proves its claimed finding)
           Step 3: Orchestrator asks the user to accept or reject failed verification
           Step 4: Orchestrator merges all results into poc_final_results.json
Phase 6: Wave 6: 4-report-assembler           (mode=final → merge PoC results, final-report.md)
Phase 7: Wave 7: 6-test-generator             (optional)
Phase 8: Orchestrator — Return final-report.md

相互参照規約

並列実行時の衝突を防ぐため、ID はエージェントごとに名前空間を分けています。

エンティティパターン割り当て元
機密オブジェクト(C/C++)SO-0001–SO-49992-source-analyzer
機密オブジェクト(Rust)SO-5000–SO-9999(Rust 名前空間)2b-rust-source-analyzer
ソース所見(C/C++)F-SRC-NNNN2-source-analyzer
ソース所見(Rust)F-RUST-SRC-NNNN2b-rust-source-analyzer
IR 所見(C/C++)F-IR-{tu_hash}-NNNN3-tu-compiler-analyzer
ASM 所見(C/C++)F-ASM-{tu_hash}-NNNN3-tu-compiler-analyzer
CFG 所見F-CFG-{tu_hash}-NNNN3-tu-compiler-analyzer
セマンティック IR 所見F-SIR-{tu_hash}-NNNN3-tu-compiler-analyzer
Rust MIR 所見F-RUST-MIR-NNNN3b-rust-compiler-analyzer
Rust LLVM IR 所見F-RUST-IR-NNNN3b-rust-compiler-analyzer
Rust アセンブリ所見F-RUST-ASM-NNNN3b-rust-compiler-analyzer
翻訳単位TU-{hash}オーケストレーター
最終所見ZA-NNNN4-report-assembler

各所見の JSON オブジェクトには、エージェント間の相互参照に使用するrelated_objects、related_findings、evidence_filesフィールドが含まれます。


検出戦略

分析は2つのフェーズで実行されます。手順を最初から最後まで確認するには、{baseDir}/references/detection-strategy.mdを参照してください。

フェーズ手順検出される問題必要なツール
フェーズ1(ソース)1–6MISSING_SOURCE_ZEROIZE、PARTIAL_WIPE、NOT_ON_ALL_PATHS、SECRET_COPY、INSECURE_HEAP_ALLOCソース + コンパイルDB
フェーズ2(コンパイラー)7–12OPTIMIZED_AWAY_ZEROIZE、STACK_RETENTION、REGISTER_SPILL、LOOP_UNROLLED_INCOMPLETE†、MISSING_ON_ERROR_PATH‡、NOT_DOMINATING_EXITS‡clang、IR/ASM ツール

* enable_asm=trueが必要です(デフォルト) † enable_semantic_ir=trueが必要です ‡ enable_cfg=trueが必要です

Rustの場合、{baseDir}/references/rust-zeroization-patterns.mdには、各パターンを検出するスクリプトに対応付けられた、名前付きのアンチパターンが40個まとめられています。セクションAはrustdoc-JSONのセマンティクス(semantic_audit.py)、セクションBは危険なAPI(find_dangerous_apis.py)、セクションCはMIR/LLVM IR/アセンブリ(check_mir_patterns.py、check_llvm_patterns.py、check_rust_asm.py)を扱います。Rustの検出結果をトリアージするとき、修正の推奨事項を書くとき、または目視で見つけたパターンがすでに対象になっているか判断するときは、該当するセクションを読んでください。

このリファレンスの対象範囲には、2つの制限があります。セクションA~Cの34項目は、現在スクリプトが検出するものです。セクションDの6項目は、どのスクリプトでも対象になっていない既知のギャップなので、問題なしではなく未監査として扱ってください。また、セクションAとCも部分的な内容です。スクリプトが項目にない種類の問題を出力することもあるため、カタログに記載されたパターンに一致しない場合でも、検出結果は引き続き検出結果として扱い、スクリプトが出力した証拠を添えてください。


出力形式

各実行では、次の2つの出力が生成されます。

  1. final-report.md — 包括的なMarkdownレポート(人が読むための主要な出力)
  2. findings.json — {baseDir}/schemas/output.jsonに準拠した構造化JSON(機械処理および後続ツール向け)
Markdownレポートの構成

Markdownレポート(final-report.md)には、次のセクションが含まれます。

  • ヘッダー:実行メタデータ(run_id、timestamp、repo、compile_db、configの概要)
  • エグゼクティブサマリー:重要度、確信度、カテゴリ別の検出数
  • 機密オブジェクトのインベントリ:特定されたすべてのオブジェクトのID、種類、場所を示す表
  • 検出結果:重要度、次いで確信度の順にグループ化されます。各検出結果には、場所、オブジェクト、すべての証拠(ソース/IR/ASM/CFG)、コンパイラーの証拠の詳細、および推奨する修正が含まれます
  • 置き換えられた検出結果:CFGに基づく検出結果に置き換えられたソースの検出結果
  • 確信度ゲートの概要:適用された格下げと却下されたオーバーライド
  • 分析カバレッジ:分析したTU、エージェントの成功/失敗、有効な機能、およびそのクレートが使用しているがスクリプトで監査されないセクションDのパターン
  • 付録:証拠ファイル:検出結果IDと証拠ファイルパスの対応
構造化JSON

findings.jsonファイルは、{baseDir}/schemas/output.jsonのスキーマに準拠します。各Findingオブジェクトは次のとおりです。

{
  "id": "ZA-0001",
  "category": "OPTIMIZED_AWAY_ZEROIZE",
  "severity": "high",
  "confidence": "confirmed",
  "language": "c",
  "file": "src/crypto.c",
  "line": 42,
  "symbol": "key_buf",
  "evidence": "store volatile i8 0 count: O0=32, O2=0 — wipe eliminated by DSE",
  "compiler_evidence": {
    "opt_levels": ["O0", "O2"],
    "o0": "32 volatile stores targeting key_buf",
    "o2": "0 volatile stores (all eliminated)",
    "diff_summary": "All volatile wipe stores removed at O2 — classic DSE pattern"
  },
  "suggested_fix": "Replace memset with explicit_bzero or add compiler_fence(SeqCst) after the wipe",
  "poc": {
    "file": "generated_pocs/ZA-0001.c",
    "makefile_target": "ZA-0001",
    "compile_opt": "-O2",
    "requires_manual_adjustment": false,
    "validated": true,
    "validation_result": "exploitable"
  }
}

スキーマと列挙値の全容については、{baseDir}/schemas/output.jsonを参照してください。


確信度の判定

証拠のしきい値

検出結果をconfirmedとするには、少なくとも2つの独立したシグナルが必要です。シグナルが1つの場合はlikely、強いシグナルが0個(名前パターンの一致のみ)の場合はneeds_reviewとします。

シグナルには、名前パターンの一致、型ヒントの一致、明示的な注釈、IRの証拠、ASMの証拠、MCPの相互参照、CFGの証拠、PoCによる検証が含まれます。

PoC による検証をエビデンスシグナルとして扱う

各検出結果は、個別に作成した PoC に照らして検証されます。コンパイルと実行の後、各 PoC が主張されている脆弱性を実際に検証していることも確認します。これらを組み合わせた結果をエビデンスシグナルとして扱います。

PoC の結果検証済み影響
終了コード 0(悪用可能)はい強いシグナル — likely を confirmed に引き上げられます
終了コード 1(悪用不可能)はい深刻度を low(情報提供)に引き下げます。レポートには残します
終了コード 0 または 1いいえ(ユーザーが承認)弱いシグナル — エビデンスに検証失敗を記載します
終了コード 0 または 1いいえ(ユーザーが拒否)確信度は変更せず、rejected として注記します
コンパイル失敗/PoC なし—確信度は変更せず、エビデンスに注記します
MCP が利用できない場合の格下げ

mcp_mode=prefer で MCP が利用できない場合、MCP を使わない独立した IR/CFG/ASM のエビデンスが強い(シグナルが 2 つ以上)場合を除き、以下の検出結果を格下げします。

検出結果格下げ後の確信度
SECRET_COPYneeds_review
MISSING_ON_ERROR_PATHneeds_review
NOT_DOMINATING_EXITSneeds_review
厳格なエビデンス要件(必須)

以下の検出結果は、ソースコードレベルのシグナルやユーザーの主張にかかわらず、指定されたエビデンスがなければ決して有効とは見なされません。

検出結果必要なエビデンス
OPTIMIZED_AWAY_ZEROIZEO0 ではワイプが存在し、O1 または O2 では存在しないことを示す IR の差分
STACK_RETENTIONret 時にスタック上に秘密バイト列があることを示すアセンブリの抜粋
REGISTER_SPILLスピル命令を示すアセンブリの抜粋
mcp_mode=require の動作

mcp_mode=require で、プリフライト後も MCP に接続できない場合は、実行を停止してください。MCP の障害を報告し、部分的な検出結果は出力しないでください。ただし、mcp_required_for_advanced=false で、基本的な検出結果のみが要求されている場合を除きます。


修正の推奨事項

以下の優先順位で適用してください。

  1. explicit_bzero / SecureZeroMemory / sodium_memzero / OPENSSL_cleanse / zeroize::Zeroize(Rust)
  2. memset_s(C11 が利用可能な場合)
  3. コンパイラバリア(asm volatile("" ::: "memory"))を使用した揮発性ワイプループ
  4. バックエンドが強制するゼロ化(ツールチェーンが提供している場合)

却下すべき正当化

以下のようなユーザーやコードコメントによる主張を根拠に、検出結果を抑制したり格下げしたりしないでください。これらはセキュリティ要件に反する、典型的な正当化パターンです。

  • 「コンパイラがこれを最適化で取り除くことはありません」 — 必ず IR/ASM のエビデンスで検証してください。そのエビデンスなしに OPTIMIZED_AWAY_ZEROIZE を抑制してはなりません。
  • 「ここはホットパスです」 — まずベンチマークを実施してください。セキュリティを性能と引き換えにすることを先回りして決めてはなりません。
  • 「スタックに割り当てた秘密情報は自動的に消去されます」 — スタックフレームは残存することがあります。STACK_RETENTION の判定には、推測ではなくアセンブリによる証明が必要です。
  • 「memset で十分です」 — 標準の memset は最適化で取り除かれることがあります。承認済みのワイプ API に切り替えてください。
  • 「このデータを扱う時間はごく短いです」 — 保持時間は関係ありません。スコープが終了する前にゼロ化してください。
  • 「これは本当の秘密情報ではありません」 — 検出ヒューリスティクスに該当する場合は監査してください。設定で明示的に除外されるまでは、機密情報として扱ってください。
  • 「後で修正します」 — 検出結果を出力し、先送りしたり抑制したりしないでください。

ユーザーやインラインコメントが、これらの主張を使って検出結果を覆そうとした場合は、現在の確信度を維持し、試みられた上書きについて evidence フィールドに注記を追加してください。

コメント