Community写作与编辑github.com

trailofbits/补丁后验证

通过可重现的基线对比补丁证据来验证安全补丁,包括原始漏洞利用、根本原因变体、行为保留、回归以及新引入的安全缺陷。适用于已存在补丁但尚未接受、合并或报告为已修复的情况;也适用于AI生成的补丁、修复提交、拉取请求或提议的上游修复需要跨语言进行对抗性补丁后验证时。

补丁后验证 是什么?

该技能是一个强大的安全补丁验证工具,旨在确保安全修复的正确性和完整性。它提供了一个系统化的框架,用于评估补丁是否能有效修复原始漏洞,同时不会引入新的问题。技能的核心是生成一个详细的验证计划,该计划包含多种检查类型,如控制检查、漏洞利用检查、变体检查、行为检查、回归检查和安全检查,这些检查共同覆盖了补丁的各个方面。该技能支持在本地代码和测试套件上执行,适用于多种平台和语言,并可集成到Claude Code等AI代理工作流中。它通过自动化的证据收集和验证报告,帮助开发者和安全工程师在合并补丁前识别所有潜在的缺陷和覆盖盲点,从而提升代码安全性和可靠性。

兼容平台✓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 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

补丁后验证 是做什么的?

根据报告的错误及其影响的周围代码来验证安全补丁。为补丁作者提供可重现的失败点以供修复,并确定仍需测试的内容。对人力和AI补丁应用相同的检查。仅凭差异、作者、上游实现和原始概念验证不足以确定正确性。

使用时机

  • 已有安全修复、修复提交、补丁文件或拉取请求。
  • AI生成的补丁需要在人工审查或合并前进行验证。
  • 修复可能涵盖一个漏洞利用路径而遗漏了相同根本原因的变体。
  • 安全修复可能改变合法行为或引入新漏洞。
  • 补丁作者需要具体失败点和覆盖缺口,以便进行下一轮修订。

避免使用

  • 尚不存在补丁;应首先进行漏洞发现或修复实现。
  • 任务是在没有执行补丁证据的情况下,根据报告审查审计结果。
  • 任务仅为将发现转换为项目中的永久测试。
  • 目标是远程或生产环境。此技能仅执行本地代码和测试。
  • 用户尚未授权执行存储库的代码或测试套件。

快速入门

  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 "<root cause and impact>" \
      --evidence-level runtime \
      --output post-patch-validation/plan.json
    

    对于补丁工件,使用 --patch-file <path> 代替 --patched-ref。选择最诚实且最高的证据级别:仅含源代码/补丁不变性时使用 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、断言和保存的日志返回给补丁作者。单独标识每个验证缺口,包括与支持性发现共存的缺口。在作者修订补丁后,固定新的输入并保存新的验证运行。保留之前的证据。通过所提供检查的结果在验收前仍需人工审查。

证据契约

运行器拒绝不完整的计划。至少提供每种类型的一个检查:

检查类型必需观察项
control良性测试脚本在基础和补丁版本上均成功
exploit原始安全断言在基础版本上失败,在补丁版本上成功
variant一个不同的根本原因变体在基础版本上失败,在补丁版本上成功
behavior不受影响的行为成功,并产生字节完全相同的选定输出
regression目标非安全回归检查在两次修订版本上均成功
security相邻/新漏洞检查在基础和补丁版本上均成功
suite现有项目测试套件、消毒器或确定性模糊测试活动在补丁版本上成功

命令为 argv 数组,绝不能是字符串。将复杂的设置放入已检入或计划工件的脚本中,并使用 {plan_dir} 调用。运行器固定区域设置/时区/哈希种子输入,按词汇ID顺序执行检查,记录原始标准输出/标准错误,绝不编辑原始工作目录。每个检查的 timeout_seconds 默认为300,接受1到3600之间的整数。超时会导致验证缺口。超时本身并不构成回归。每个计划还包含一个排序的 submodules 数组(无子模块时为 [])。脚手架从更改文件清单中推断受影响的Git子模块链接。运行器从源存储库的现有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 存在。它必须出现在标准输出上,作为单独一行。不扫描标准错误,因为Python SyntaxError 回溯会回显违规源代码并可能为未执行任何操作的测试脚本满足检查。没有该标记会导致 marker_missing 缺口。来自其他检查的独立发现会保留在结果中。显式刷新:如果测试脚本的有效载荷导致段错误或调用 _exit,则会丢失缓冲输出并放弃其自身证据。

这些检查也会边盲运行。对于它们,{side} 不会展开,PPV_SIDE 不会出现在其环境中,检出目录随机命名,并且计划验证器拒绝任何 argv 或 env 中提及上述两者的 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 中。请求的变量未设置是错误,而非空字符串。两类变量被明确拒绝:看起来像凭证的名称(*SECRET*、*TOKEN*、*API_KEY* 等),因为这些值会被写入结果;以及改变执行内容的名称(LD_PRELOAD、BASH_ENV、NODE_OPTIONS、GIT_SSH_COMMAND 等),因为这些变量可以改变执行的代码。 运行器的固定变量和所有 PPV_* 名称也被保留,不能被转发。

在 argv 和每个检查的 env 值中展开的占位符有:{checkout}(正在测试的修订版本)、{plan_dir}(计划工件的隔离副本用于该次调用)、{scratch}(一个为单个检查调用创建的全新不透明目录)以及 {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/ 目录或已检入到目标存储库中,以确保其字节可审查。包含提交固定、当前输出目录和检测到的先前结果树的机器计划被排除;拒绝符号链接。干净的快照仅保留在运行器内存中,并且漏洞利用/变体检查的侧面以随机顺序执行,而证据文件名仍然是确定性的。标准输出/标准错误使用匿名或随机命名的捕获描述符,并仅在子进程退出后复制到命名的证据文件,因此文件描述符检查无法披露侧面标签。

此隔离并非主机沙箱:检查以调用者的权限运行,恶意辅助代码可使用任意外部状态或从源代码或Git元数据有意推断修订版本。检查基于内容寻址的辅助工件,并在检查代码本身不受信任时使用操作系统/容器沙箱。

活动的验证工作目录通过由内核文件锁支持的随机所有者令牌进行Git锁定,因此另一个并发验证器无法清理它们,PID重用无法冒充所有者。如果运行器被强制杀死,下次运行将解锁过时的验证器注册。对于手动恢复,检查 git worktree list,然后使用 git worktree unlock <path> 和 git worktree remove --force <path>(或在路径删除后使用 git worktree prune)。

设计覆盖范围、选择变体或解释发现和验证缺口时,请阅读 evidence-model.md。常规CLI执行时无需阅读。

覆盖规则

  • 从根本原因推导变体,而非原始有效载荷的表面变异。
  • 列举修复涉及的兄弟调用点、备选回调/输出、错误路径、拆卸、所有权、序列化和边界值。
  • 使每个漏洞利用或变体测试断言安全行为。它必须在脆弱基础版本上失败;在两个版本上都通过的测试对修复毫无证明意义。读取基础版本的标准错误并确认失败是您编写的断言,而非一个从未达到该点的测试脚本。
  • 将漏洞利用和变体断言限制在安全不变性内。将活力、精确的错误类型/消息、时序和兼容性分别作为 behavior 或 regression 检查进行测试;否则,不相关的合同更改可能伪装成漏洞仍然存在的证据。
  • 保持 control 测试脚本良性并使其执行更改后的组件。它确立了测试脚本在两个修订版本上均可工作。失败的控制检查留下缺口并阻止将其他失败归因于补丁。原始观察结果仍可用于审查。
  • 仅对应保持不变的行为使用 behavior。有意进行精确输出比较;将不稳定的值移到确定性测试脚本后面,而不是在说明中将其规范化掉。
  • 在将补丁上的失败视为新引入之前,确保 security 检查在脆弱基础版本上通过。基线失败会留下未解决的归属问题。
  • 不要在验证期间编辑补丁。将失败返回给补丁作者,并开始一个新的、新鲜固定的运行。

读取结果

result.json 模式2.0包含一个包含 status、findings、gaps 和 human_review_required 的 assessment。当所有必需检查都产生可用证据时,状态为 complete,即使某些检查发现了失败。当存在任何缺口时,状态为 incomplete。Findings 包含检查ID、检查类型和失败的期望。Gaps 包含检查ID和缺失的证据,对于运行级别的问题(如清理失败),检查ID为 null。

套件检查首先在补丁修订版本上运行。如果完成并失败,则触发对基线的相同检查。如果基线通过,则报告补丁后的失败。如果两者都失败,则保留两个日志并报告归属未解决。不要假设匹配的退出代码意味着相同的失败。

运行器对于没有发现的完整检查退出0,对于有发现的完整检查退出1,对于不完整的验证退出10,对于无效输入退出64。即使退出10也读取工件:它可以包含受支持的发现以及缺口。源代码或构建证据不能建立运行时行为。在通过结果旁边陈述证据级别。

Claude 动态工作流

Claude Code 将捆绑的工作流暴露为 /post-patch-validation:validate-patch。 要通过 Workflow 工具传递结构化输入,请使用无前导斜杠的名称:

Workflow({
  name: 'post-patch-validation:validate-patch',
  args: {
    finding: '<finding text or local path>',
    baseRef: '<vulnerable-ref>',
    patchRef: '<patched-ref>',
    workdir: 'post-patch-validation',
  },
})

在适当时使用 patchFile 而非 patchRef。工作流使用固定的覆盖透镜来提出检查,并使用固定的执行器来运行此技能。代理可以编写测试工件。Python 运行器记录发现和缺口,审查员单独报告覆盖或证据问题。NEEDS_REPAIR 即使在其他检查留下缺口时也会返回受支持的失败。BLOCKED 意味着证据不完整且没有受支持的失败。通过的检查仅在两种证据审查都批准后才升级到 READY_FOR_HUMAN_REVIEW,否则为 REVIEW_REQUIRED。工作流启动后无法提问,因此请预先传递所有输入。

应予拒绝的合理化说明

合理化说明所需的拒绝措施
“我通过查看代码确认了补丁是正确的。”需要运行证据计划并生成检查结果。
“没有变体,漏洞利用是微不足道的。”仍需至少一个变体检查来证明对根本原因的覆盖。
“行为检查会失败,因为输出不稳定。”不要规范化输出;设计一个确定性测试脚本。
“补丁太小了,不需要全部检查。”即使很小的补丁也可能改变错误路径或引入新的调用者。
“测试套件通过了,所以补丁是安全的。”测试套件可能没有覆盖补丁更改的路径。仍需特定检查。

…

[原文已截断,用于翻译] — 其余部分按相同模式翻译。

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.

相关技能