Communityライティング&編集github.com

trailofbits/post-patch-validation

セキュリティパッチを再現可能なベースライン対パッチ適用済みの証拠とともに検証し、元のエクスプロイト、根本原因のバリアント、動作維持、リグレッション、新たに導入されたセキュリティ障害を含めます。パッチが存在し、それを受け入れたりマージしたり、修正済みとして報告する前に使用します。また、AIが生成したパッチ、修正コミット、プルリクエスト、提案されたアップストリーム修正が、あらゆる言語にわたって敵対的なポストパッチ検証を必要とする場合にも使用します。

post-patch-validation とは?

Post-Patch Validationは、セキュリティパッチの正しさを再現可能かつ証拠に基づいて検証するためのAIエージェントスキルです。このスキルは、Claude Code(CLI/Workflow)、Cursor、CodexなどのAIエージェントが、既存のパッチやAI生成パッチに対して、元の脆弱性の再現、根本原因のバリアントの検証、正常動作の維持確認、リグレッションのチェック、新たなセキュリティ問題の有無を自動的に評価します。サポートする証拠レベルは、ソースコード分析(source)、ビルド分析(build)、ランタイム実行(runtime)の3段階で、ユーザーは最も正直なレベルを選択できます。スキルはPythonスクリプトとして実装され、`uv run`で実行され、証拠計画(plan.json)の作成、検証、実行、結果報告の一連のワークフローを提供します。証拠はJSONとMarkdownレポートで出力され、各チェックの成功/失敗とそのログが詳細に記録されます。チェックには、コントロール(control)、エクスプロイト(exploit)、バリアント(variant)、動作(behavior)、リグレッション(regression)、セキュリティ(security)、スイート(suite)の7種類があり、すべての種類のチェックを少なくとも1つ含める必要があります。エクスプロイトチェックとバリアントチェックは、サイドブラインド(checkoutがベースかパッチかを認識できない)で実行され、証拠として`PPV_REACHED`マーカーを標準出力に出力する必要があります。このスキルは、パッチ作成者に対して具体的な失敗とカバレッジのギャップを提供し、人間のレビューに先立って使用することを意図しています。

対応✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/trailofbits/skills/tree/main/plugins/post-patch-validation/skills/post-patch-validation

Installed? Explore more ライティング&編集 skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

ポストパッチ検証

報告されたバグとその影響を受ける周辺コードに対してセキュリティパッチを検証します。パッチ作成者に再現可能な失敗を提供し、まだテストが必要な部分を特定します。人間が作成したパッチとエージェントが生成したパッチに同じチェックを適用します。差分、作者、アップストリームの実装、元の概念実証だけでは正しさを確立できません。

使用するタイミング

  • セキュリティ修正、修正コミット、パッチファイル、またはプルリクエストがすでに存在する場合。
  • AIが生成したパッチを人間のレビューまたはマージの前に検証する必要がある場合。
  • 修正が1つのエクスプロイト経路をカバーしているが、同じ根本原因のバリアントを見逃している可能性がある場合。
  • セキュリティ修正が正当な動作を変更したり、新しい脆弱性を導入する可能性がある場合。
  • パッチ作成者が別のリビジョンを作成する前に、具体的な失敗とカバレッジのギャップを必要としている場合。

使用してはいけないタイミング

  • パッチがまだ存在しない場合。代わりに脆弱性の発見または修正の実装を先に行います。
  • 監査結果をレポートに対して確認するタスクで、パッチの証拠を実行しない場合。
  • タスクが単に監査結果を恒久的なプロジェクトテストに変換することだけの場合。
  • 対象がリモートまたは本番環境の場合。このスキルはローカルコードとテストのみを実行します。
  • ユーザーがリポジトリのコードまたはテストスイートの実行を許可していない場合。

クイックスタート

  1. 脆弱なベースとパッチ適用済みの入力を固定します。不変のコミットを推奨します。コミットされていない作業の場合は、最初にバイナリパッチファイルを作成します。ユーザーのワーキングツリーで検証しないでください。

  2. 固定された計画をスキャフォールドします:

    uv run {baseDir}/scripts/post_patch_validation.py scaffold \
      --repo . \
      --base-ref <vulnerable-ref> \
      --patched-ref <patched-ref> \
      --finding-id <stable-id> \
      --finding-summary "<根本原因と影響>" \
      --evidence-level runtime \
      --output post-patch-validation/plan.json
    

    --patched-refの代わりに--patch-file <path>を使用してパッチアーティファクトを指定します。最も正直な証拠レベルを選択してください: source(ソース/パッチ不変条件のみ)、build(ターゲットコードがコンパイルまたは分析されるが、報告された動作は実行されない)、runtime(チェックが報告された動作とその安全アサーションを実行する)。

  3. 調査結果、差分、呼び出し元、兄弟パス、クリーンアップ/エラーパス、既存のテストを検査します。生成された計画にchecksを追加します。構造スキーマを表示するには print-schema を実行します:

    uv run {baseDir}/scripts/post_patch_validation.py print-schema
    
  4. コードを実行する前に、カバレッジ、コマンド制限、固定入力を含む完全な検証のために validate-plan を実行します:

    uv run {baseDir}/scripts/post_patch_validation.py validate-plan \
      --plan post-patch-validation/plan.json
    
  5. 証拠計画を実行します:

    uv run {baseDir}/scripts/post_patch_validation.py run \
      --plan post-patch-validation/plan.json \
      --output post-patch-validation/results
    
  6. result.json、report.md、証拠レベル、および完全なassessmentを報告します。各調査結果を、そのチェックID、アサーション、保存されたログとともにパッチ作成者に返します。サポートされている調査結果と共存するギャップを含め、各検証ギャップを個別に特定します。作成者がパッチを修正した後、新しい入力を固定し、新しい検証実行を保存します。以前の証拠は保持します。提供されたチェックに合格しても、受け入れ前にはまだ人間によるレビューが必要です。

証拠コントラクト

ランナーは不完全な計画を拒否します。すべての種類のチェックを少なくとも1つ提供してください:

種類必要な観測結果
control良性ハーネスがベースとパッチの両方で成功する
exploit元の安全アサーションがベースで失敗し、パッチで成功する
variant異なる根本原因バリアントがベースで失敗し、パッチで成功する
behavior影響を受けない動作が、バイト同一の選択された出力で成功する
regression対象となる非セキュリティリグレッションチェックが両方のリビジョンで成功する
security隣接/新しい脆弱性のチェックがベースとパッチの両方で成功する
suite既存のプロジェクトスイート、サニタイザー、または決定論的ファズキャンペーンがパッチで成功する

コマンドはargv配列であり、シェル文字列ではありません。複雑なセットアップはチェックインまたは計画アーティファクトスクリプトに配置し、{plan_dir}で呼び出します。ランナーはロケール/タイムゾーン/ハッシュシード入力を固定し、チェックを辞書順IDで実行し、生のstdout/stderrを記録し、元のワークツリーを決して編集しません。各チェックのtimeout_secondsはデフォルトで300で、1から3600までの整数を受け入れます。タイムアウトを超えると検証ギャップが残ります。タイムアウトだけではリグレッションは確定しません。すべての計画にはソートされたsubmodules配列も含まれます(ない場合は[])。スキャフォールディングは、変更されたファイルのインベントリから影響を受けるGitlinkを推測します。ランナーは、ソースリポジトリの既存のGitモジュールオブジェクトからこれらの固定コミットを初期化し、.gitmodulesのネットワークURLからは決して初期化しません。検証の前に、ソースリポジトリでそれらを初期化またはフェッチしてください。

エクスプロイトとバリアントチェックは実行されたことを証明する必要があります

ゼロ以外の終了コードは、脆弱性が再現されたことを意味しません。インポートエラー、ビルド失敗、依存関係の欠落、安全アサーションの失敗はすべてゼロ以外で終了し、ランナーからは区別できません。すべてのexploitおよびvariantチェックは、両方のリビジョンで、アサーションを評価する直前にPPV_REACHEDを出力してフラッシュする必要があります:

"argv": ["python3", "-c", "import app; value = app.render('<'); print('PPV_REACHED', flush=True); assert value == '&lt;"]

このトークンは環境変数PPV_REACHED_MARKERとしても利用できます。これは標準出力に、独自の行として出力されなければなりません。stderrはスキャンされません。なぜなら、PythonのSyntaxErrorトレースバックは問題のソースをエコーし、何も実行しなかったハーネスに対してチェックを満たしてしまうからです。これがない実行はmarker_missingギャップを残します。他のチェックからの独立した調査結果は結果に残ります。明示的にフラッシュしてください: ペイロードがセグメンテーションフォールトを起こしたり_exitを呼び出したりするハーネスは、バッファリングされた出力を失い、自身の証拠を無効にします。

これらのチェックはサイドブラインドでも実行されます。{side}はそれらに対して展開されず、PPV_SIDEは環境に存在せず、チェックアウトディレクトリはランダムに名前が付けられ、計画バリデーターはargvまたはenvのいずれかに{side}またはPPV_SIDEを含むexploitまたはvariantチェックを拒否します。自分がどのリビジョンにいるかを見ることができるアサーションは、コードに対してではなくそれに対してアサーションを行うことができ、これは再現とその後の修正を偽装する最も安価な方法です。

環境

チェックは固定された最小限の環境で実行されます: PATH、HOME、および少数の一時/ユーザーキーに加えて、LANG/LC_ALL=C、TZ=UTC、PYTHONHASHSEED=0、NO_COLOR、TERM=dumb。呼び出し側の環境の残りはすべて削除されます。さらに必要とするツールチェーンは明示的に指定します:

uv run {baseDir}/scripts/post_patch_validation.py run \
  --plan post-patch-validation/plan.json \
  --output post-patch-validation/results \
  --allow-env JAVA_HOME --allow-env CARGO_HOME

転送された名前と値はresult.jsonに記録されます。要求された変数が設定されていない場合は、空の文字列ではなくエラーになります。2つのクラスは完全に拒否されます: 資格情報として読み取れる名前(*SECRET*、*TOKEN*、*API_KEY*など)。値が結果に書き込まれるためです。そして、実行内容を変更する名前(LD_PRELOAD、BASH_ENV、NODE_OPTIONS、GIT_SSH_COMMANDなど)。これらの変数は実行されるコードを変更できるためです。ランナーの固定変数とすべてのPPV_*名も予約されており、転送できません。

argvおよびチェックごとのenv値で展開されるプレースホルダー: {checkout}(テスト対象のリビジョン)、{plan_dir}(その1回の呼び出し用の計画アーティファクトの分離されたコピー)、{scratch}(その1回のチェック呼び出し用の新しい不透明なディレクトリ)、および{side}(baseまたはpatched、exploit/variantチェックでは使用不可)。同じ値がPPV_CHECKOUT、PPV_PLAN_DIR、PPV_SCRATCH、PPV_SIDE、PPV_CASE_IDとして提供されます。{scratch}の下にのみ書き込みます。証拠ディレクトリのパスはチェックに渡されません。ベースとパッチの呼び出しは、ランナー管理のスクラッチ、計画、またはワークツリールートを共有しません。各呼び出しが終了すると、そのスクラッチツリーは決定論的なresults/scratch/<check-id-and-side>パスの下にアーカイブされ、プライベートな計画コピーは破棄され、ファイルに解決される読み取り可能な各argv要素はargv_filesでハッシュ化されます。分離された計画またはチェックアウトルート内のファイルは、さらにresults/helpers/<sha256>の下に最大16 MiBまで保持されます。レコードは、他のファイルがアーカイブされなかった理由を説明します。plan.jsonには専用のディレクトリを使用してください。その兄弟ファイルとディレクトリは、各呼び出しの{plan_dir}にコピーされます。ヘルパーコードはそのディレクトリのchecks/ディレクトリの下、またはターゲットリポジトリにチェックインして、そのバイトがレビュー可能になるようにしてください。コミットピン、現在の出力ディレクトリ、および検出された以前の結果ツリーを含むマシン計画は除外されます。シンボリックリンクは拒否されます。クリーンなスナップショットはランナーメモリにのみ残り、エクスプロイト/バリアントのサイドはランダムな順序で実行されますが、証拠ファイル名は決定論的です。Stdout/stderrは匿名またはランダムに名前が付けられたキャプチャ記述子を使用し、子プロセスが終了した後にのみ名前付き証拠ファイルにコピーされるため、fd検査でサイドラベルが漏洩することはありません。

この隔離はホストサンドボックスではありません。チェックは呼び出し側の権限で実行され、悪意のあるヘルパーは任意の外部状態を使用したり、ソースまたはGitメタデータからリビジョンを意図的に推測したりする可能性があります。コンテンツアドレス指定されたヘルパーアーティファクトを検査し、チェックコード自体が信頼できない場合は、OS/コンテナサンドボックスを使用してください。

アクティブな検証ワークツリーは、カーネルファイルロックによってバックアップされたランダムな所有者トークンでGitロックされるため、別の同時バリデーターがそれらを削除できず、PIDの再利用が所有者を偽装することはできません。ランナーが強制終了された場合、次の実行は古いバリデーター所有の登録をロック解除します。手動で回復するには、git worktree listを検査し、次にgit worktree unlock <path>とgit worktree remove --force <path>を使用します(パスがなくなった後はgit worktree prune)。

カバレッジの設計、バリアントの選択、または調査結果と検証ギャップの解釈には、evidence-model.mdを読んでください。日常的なCLI実行のためにそれを読む必要はありません。

カバレッジルール

  • 元のペイロードの表面的な変形ではなく、根本原因からバリアントを導出します。
  • 修正によって影響を受ける、兄弟呼び出しサイト、代替コールバック/出力、エラーパス、後処理、所有権、シリアル化、および境界値を列挙します。
  • 各エクスプロイトまたはバリアントテストに安全な動作をアサートさせます。脆弱なベースで失敗する必要があります。両方のリビジョンで合格するテストは、修正について何も証明しません。ベース側のstderrを読み取り、失敗があなたが書いたアサーションであり、そこに到達しなかったハーネスではないことを確認してください。
  • エクスプロイトとバリアントのアサーションをセキュリティ不変条件に限定します。生存性、正確なエラータイプ/メッセージ、タイミング、および互換性は、別途behaviorまたはregressionチェックとしてテストしてください。そうしないと、無関係な契約変更が脆弱性が残っていることの証明になりすます可能性があります。
  • controlハーネスは良性に保ち、変更されたコンポーネントを実行させます。これにより、ハーネスが両方のリビジョンで機能することが確立されます。コントロールの失敗はギャップを残し、他の失敗をパッチに帰属させることを妨げます。生の観測結果はレビューのために引き続き利用できます。
  • behaviorは、変更されるべきではない動作にのみ使用します。正確な出力比較は意図的なものです。不安定な値は、説明文で正規化して取り除くのではなく、決定論的なテストハーネスの背後に移動してください。
  • securityチェックは、パッチ適用後の失敗を新たに導入されたものとして扱う前に、脆弱なベースで合格するようにしてください。ベースラインの失敗は帰属を未解決のままにします。
  • 検証中にパッチを編集しないでください。失敗をパッチ作成者に返し、新しく固定された新しい実行を開始してください。

結果の読み方

result.jsonスキーマ2.0には、status、findings、gaps、およびhuman_review_requiredを持つassessmentが含まれています。ステータスは、すべての必須チェックが使用可能な証拠を生成した場合(一部のチェックで失敗が見つかった場合でも)completeになります。ギャップが残っている場合、ステータスはincompleteです。調査結果は、チェックID、チェック種類、および失敗した期待値を示します。ギャップは、チェックIDと欠落している証拠を示し、実行レベルの問題(クリーンアップ失敗など)の場合はチェックIDがnullになります。

スイートチェックは最初にパッチ適用されたリビジョンで実行されます。完了した失敗は、同じチェックをベースラインでトリガーします。ベースラインが合格した場合、パッチ後の失敗を報告します。両方が失敗した場合、両方のログを保持し、帰属が未解決であることを報告します。終了コードが同じことが同じ失敗を意味するとは想定しないでください。

ランナーは、調査結果のない完全なチェックの場合は0で終了し、調査結果のある完全なチェックの場合は1で終了し、不完全な検証の場合は10で終了し、無効な入力の場合は64で終了します。終了コード10の場合でもアーティファクトを読んでください。ギャップとともにサポートされている調査結果が含まれている可能性があります。ソースまたはビルドの証拠はランタイム動作を確立できません。合格結果と一緒に証拠レベルを記載してください。

Claude Dynamic Workflow

Claude Codeはバンドルされたワークフローを/post-patch-validation:validate-patchとして公開します。Workflowツールを通じて構造化入力を渡すには、先頭のスラッシュなしの名前を使用してください:

Workflow({
  name: 'post-patch-validation:validate-patch',
  args: {
    finding: '<調査結果のテキストまたはローカルパス>',
    baseRef: '<脆弱なリファレンス>',
    patchRef: '<パッチ適用されたリファレンス>',
    workdir: 'post-patch-validation',
  },
})

必要に応じてpatchRefの代わりにpatchFileを使用します。ワークフローは固定されたカバレッジレンズを使用してチェックを提案し、固定されたエグゼキュータを使用してこのスキルを実行します。エージェントはテストアーティファクトを作成する場合があります。Pythonランナーは調査結果とギャップを記録し、レビュアーはカバレッジまたは証拠の問題を個別に報告します。NEEDS_REPAIRは、他のチェックがギャップを残した場合でも、サポートされている失敗を返します。BLOCKEDは、サポートされている失敗なしでは証拠が不完全であることを意味します。合格したチェックは、両方の証拠レビューが承認した後にのみREADY_FOR_HUMAN_REVIEWに進みます。そうでない場合はREVIEW_REQUIREDになります。ワークフローは起動後に質問をすることができないため、すべての入力を事前に渡してください。

拒否すべき正当化

正当化必要な再対応
パッチは単純です簡潔さは正しさではありません。検証をスキップしないでください。
テストがパスします既存のテストは未知のバリアントをカバーしていません。
コードレビューが承認しましたレビューだけでは実行時の動作を証明できません。
ツールが生成しましたすべての出力は同じ検証基準を満たさなければなりません。
以前は機能していましたリビジョンが異なれば動作も異なります。

トラブルシューティング

  • 計画検証エラー: validate-planの出力を確認し、すべての必須フィールドが存在することを確認してください。
  • 証拠マーカーが見つからない: エクスプロイト/バリアントのハーネスがPPV_REACHEDをstdoutにフラッシュしていることを確認してください。
  • タイムアウト: タイムアウト値を増やすか、チェックの複雑さを軽減してください。
  • 依存関係の欠落: チェックが依存関係を明示的にインストールしているか、または環境に存在することを確認してください。
  • Gitワークツリーエラー: git worktree listを実行し、古いロックをクリーンアップしてください。
  • 環境変数エラー: --allow-envで転送するすべての変数が設定されていることを確認してください。

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

trailofbits/address-sanitizer

AddressSanitizer detects memory errors during fuzzing. Use when fuzzing C/C++ code to find buffer overflows and use-after-free bugs.

trailofbits/aflpp

AFL++ is a fork of AFL with better fuzzing performance and advanced features. Use for multi-core fuzzing of C/C++ projects.

trailofbits/agentic-actions-auditor

Audits GitHub Actions workflows for security vulnerabilities in AI agent integrations including Claude Code Action, Gemini CLI, OpenAI Codex, and GitHub AI Inference. Detects attack vectors where attacker-controlled input reaches AI agents running in CI/CD pipelines, including env var intermediary patterns, direct expression injection, dangerous sandbox configurations, and wildcard user allowlists. Use when reviewing workflow files that invoke AI coding agents, auditing CI/CD pipeline security for prompt injection risks, or evaluating agentic action configurations.

trailofbits/algorand-vulnerability-scanner

Scans Algorand smart contracts for 11 common vulnerabilities including rekeying attacks, unchecked transaction fees, missing field validations, and access control issues. Use when auditing Algorand projects (TEAL/PyTeal).

trailofbits/ask-questions-if-underspecified

Clarify requirements before implementing. Use when serious doubts arise.

trailofbits/atheris

Atheris is a coverage-guided Python fuzzer based on libFuzzer. Use for fuzzing pure Python code and Python C extensions.

trailofbits/audit-augmentation

Augments Trailmark code graphs with external audit findings from SARIF static analysis results and weAudit annotation files. Maps findings to graph nodes by file and line overlap, creates severity-based subgraphs, and enables cross-referencing findings with pre-analysis data (blast radius, taint, etc.). Use when projecting SARIF results onto a code graph, overlaying weAudit annotations, cross-referencing Semgrep or CodeQL findings with call graph data, or visualizing audit findings in the context of code structure.

trailofbits/audit-context-building

Enables ultra-granular, line-by-line code analysis to build deep architectural context before vulnerability or bug finding.

trailofbits/audit-prep-assistant

Prepares codebases for security review using Trail of Bits' checklist. Helps set review goals, runs static analysis tools, increases test coverage, removes dead code, ensures accessibility, and generates documentation (flowcharts, user stories, inline comments).

trailofbits/burpsuite-project-parser

Searches and explores Burp Suite project files (.burp) from the command line. Use when searching response headers or bodies with regex patterns, extracting security audit findings, dumping proxy history or site map data, or analyzing HTTP traffic captured in a Burp project.

trailofbits/cairo-vulnerability-scanner

Scans Cairo/StarkNet smart contracts for 6 critical vulnerabilities including felt252 arithmetic overflow, L1-L2 messaging issues, address conversion problems, and signature replay. Use when auditing StarkNet projects.

trailofbits/cargo-fuzz

cargo-fuzz is the de facto fuzzing tool for Rust projects using Cargo. Use for fuzzing Rust code with libFuzzer backend.

trailofbits/chrome-mcp-troubleshooting

Diagnose and fix Claude in Chrome MCP extension connectivity issues. Use when mcp__claude-in-chrome__* tools fail, return "Browser extension is not connected", or behave erratically.

trailofbits/claude-in-chrome-troubleshooting

Diagnose and fix Claude in Chrome MCP extension connectivity issues. Use when mcp__claude-in-chrome__* tools fail, return "Browser extension is not connected", or behave erratically.

trailofbits/code-improver

Runs an autonomous review-and-fix improvement loop over any code target — a skill, plugin, module, or directory — using a reviewer the user names: any installed skill or agent. Keeps a cross-round findings ledger, escalates when fixes stop converging, and guards scope mechanically. Use when asked to 'improve this code until review passes', 'run an improvement loop with <reviewer>', or to iterate review-and-fix with a specific reviewer. For skills prefer the skill-improver entry; for a branch prefer pr-improver.

trailofbits/code-maturity-assessor

Systematic code maturity assessment using Trail of Bits' 9-category framework. Analyzes codebase for arithmetic safety, auditing practices, access controls, complexity, decentralization, documentation, MEV risks, low-level code, and testing. Produces professional scorecard with evidence-based ratings and actionable recommendations.

trailofbits/codeql

Scans a codebase for security vulnerabilities using CodeQL's interprocedural data flow and taint tracking analysis. Triggers on "run codeql", "codeql scan", "codeql analysis", "build codeql database", or "find vulnerabilities with codeql". Supports "run all" (security-and-quality + security-experimental suites) and "important only" (high-precision security findings) scan modes. Also handles creating data extension models and processing CodeQL SARIF output.

trailofbits/constant-time-analysis

Detects timing side-channel vulnerabilities in cryptographic code. Use when implementing or reviewing crypto code, encountering division on secrets, secret-dependent branches, or constant-time programming questions in C, C++, Go, Rust, Swift, Java, Kotlin, C#, PHP, JavaScript, TypeScript, Python, or Ruby.

trailofbits/constant-time-testing

Constant-time testing detects timing side channels in cryptographic code. Use when auditing crypto implementations for timing vulnerabilities.

trailofbits/cosmos-vulnerability-scanner

Scans Cosmos SDK blockchain modules and CosmWasm contracts for consensus-critical vulnerabilities — chain halts, fund loss, state divergence. 25 core + 16 IBC + 10 EVM + 3 CosmWasm patterns. Use when auditing custom x/ modules, reviewing IBC integrations, or assessing pre-launch chain security. Updated for SDK v0.53.x.

関連スキル