CommunityEscrita e Ediçãogithub.com

validação-de-patch-pós-aplicação

Valida patches de segurança com evidências reprodutíveis de linha de base versus patch, incluindo explorações originais, variantes de causa raiz, preservação de comportamento, regressões e novas falhas de segurança introduzidas. Use após um patch existir e antes de aceitá-lo, mesclá-lo ou relatá-lo como corrigido; também use quando um patch gerado por IA, commit de correção, pull request ou correção upstream proposta precisar de validação adversária pós-patch em qualquer linguagem.

O que é validação-de-patch-pós-aplicação?

Esta skill realiza uma validação rigorosa e sistemática de patches de segurança, gerando evidências reprodutíveis sobre a eficácia da correção. Ela é projetada para ser usada após a existência de uma correção (seja humana ou gerada por IA) e antes de sua aceitação, mesclagem ou publicação. A skill suporta qualquer tipo de patch (commits, arquivos de patch, pull requests) e qualquer linguagem de programação, executando localmente no repositório clonado. O fluxo de trabalho principal envolve: (1) fixar as versões vulnerável e corrigida (usando refs imutáveis ou arquivos de patch binário), (2) gerar um plano de validação estruturado (com checks de controle, exploração, variante, comportamento, regressão, segurança e suíte de testes), (3) validar o plano, (4) executar os checks em ambiente isolado e de forma cega (sem que os testes saibam se estão na base ou no patch), e (5) reportar os resultados com evidências detalhadas. A skill é implementada em Python (via `uv run scripts/post_patch_validation.py`) e integrada ao Claude Code por meio de um workflow dinâmico (`/post-patch-validation:validate-patch`). Ela impõe um contrato de evidências rigoroso: cada plano deve conter checks de todos os tipos obrigatórios, os checks de exploração e variante devem provar que realmente executaram (imprimindo 'PPV_REACHED' no stdout), e a execução é feita em ambiente mínimo e isolado para evitar contaminação. O resultado é um relatório completo com status, descobertas, lacunas e indicação se revisão humana é necessária. A utilidade da skill reside em sua capacidade de detectar não apenas se a exploração original foi corrigida, mas também se variantes da mesma causa raiz persistem, se o comportamento legítimo foi preservado, se novas regressões ou vulnerabilidades foram introduzidas, e se a suíte de testes existente continua funcionando. Ela substitui a confiança cega em diffs ou autores por evidências baseadas em execução, fornecendo ao autor do patch falhas concretas e lacunas de cobertura que precisam ser endereçadas antes de uma segunda rodada de revisão.

Funciona com✓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 Escrita e Edição skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Validação de Patch Pós-Aplicação

Valide um patch de segurança contra o bug relatado e o código ao redor que ele afeta. Forneça ao autor do patch falhas reprodutíveis para corrigir e identifique o que ainda precisa de teste. Aplique as mesmas verificações a patches humanos e de agentes. O diff, o autor, a implementação original e a prova de conceito original sozinhos não podem estabelecer a correção.

Quando Usar

  • Uma correção de segurança, commit de correção, arquivo de patch ou pull request já existe.
  • Um patch gerado por IA precisa de validação antes da revisão humana ou mesclagem.
  • Uma correção pode cobrir um caminho de exploração enquanto perde variantes da mesma causa raiz.
  • Uma correção de segurança pode alterar o comportamento legítimo ou introduzir uma nova vulnerabilidade.
  • O autor do patch precisa de falhas concretas e lacunas de cobertura antes de uma nova revisão.

Quando NÃO Usar

  • Nenhum patch existe ainda; use descoberta de vulnerabilidade ou implementação de correção primeiro.
  • A tarefa é revisar um achado de auditoria contra um relatório sem executar evidências do patch.
  • A tarefa é apenas converter um achado em um teste permanente do projeto.
  • O alvo é remoto ou produção. Esta skill executa código e testes locais apenas.
  • O usuário não autorizou a execução do código ou suíte de testes do repositório.

Início Rápido

  1. Fixe a base vulnerável e a entrada corrigida. Prefira commits imutáveis. Para trabalho não commitado, crie um arquivo de patch binário primeiro; não valide na árvore de trabalho do usuário.

  2. Estruture um plano fixado:

    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
    

    Use --patch-file <path> em vez de --patched-ref para um artefato de patch. Escolha o nível de evidência mais alto honesto: source apenas para invariantes de fonte/patch, build quando o código alvo é compilado ou analisado, mas o comportamento relatado não é executado, ou runtime quando as verificações executam o comportamento relatado e suas asserções de segurança.

  3. Inspecione o achado, diff, chamadores, caminhos irmãos, caminhos de limpeza/erro e testes existentes. Popule checks no plano gerado. Execute print-schema para o esquema estrutural:

    uv run {baseDir}/scripts/post_patch_validation.py print-schema
    
  4. Execute validate-plan para a validação completa, incluindo cobertura, restrições de comando, e entradas fixadas, antes de executar o código:

    uv run {baseDir}/scripts/post_patch_validation.py validate-plan \
      --plan post-patch-validation/plan.json
    
  5. Execute o plano de evidências:

    uv run {baseDir}/scripts/post_patch_validation.py run \
      --plan post-patch-validation/plan.json \
      --output post-patch-validation/results
    
  6. Reporte result.json, report.md, o nível de evidência e a assessment completa. Retorne cada achado ao autor do patch com seu ID de verificação, asserção e logs salvos. Identifique cada lacuna de validação separadamente, incluindo lacunas que coexistem com achados suportados. Após o autor revisar o patch, fixe as novas entradas e salve uma nova execução de validação. Preserve a evidência anterior. Verificações fornecidas que passam ainda requerem revisão humana antes da aceitação.

Contrato de Evidências

O executor rejeita planos incompletos. Forneça pelo menos uma verificação de cada tipo:

TipoObservação obrigatória
controlHarness benigno tem sucesso tanto na base quanto no patch
exploitAsserção de segurança original falha na base e tem sucesso no patch
variantUma variante distinta da causa raiz falha na base e tem sucesso no patch
behaviorComportamento não afetado tem sucesso com saída selecionada byte-idêntica
regressionVerificação de regressão não relacionada à segurança tem sucesso em ambas as revisões
securityVerificação de vulnerabilidade adjacente/nova tem sucesso na base e no patch
suiteSuíte existente do projeto, sanitizer ou campanha de fuzz determinística tem sucesso no patch

Comandos são arrays argv, nunca strings de shell. Coloque configuração complexa em um script verificado ou artefato do plano e invoque-o com {plan_dir}. O executor fixa entradas de locale/timezone/hash-seed, executa verificações em ordem lexical de ID, registra stdout/stderr bruto e nunca edita a árvore de trabalho original. O timeout_seconds de cada verificação padrão é 300 e aceita inteiros de 1 a 3600. Exceder o tempo limite deixa uma lacuna de validação. Um tempo limite sozinho não estabelece uma regressão. Cada plano também contém um array submodules ordenado ([] quando nenhum). O scaffolding infere Gitlinks afetados a partir do inventário de arquivos alterados. O executor inicializa esses commits fixados dos objetos do módulo Git existentes do repositório de origem, nunca de URLs de rede .gitmodules; inicialize ou busque-os no repositório de origem antes da validação.

Verificações de exploração e variante devem provar que foram executadas

Uma saída diferente de zero não significa que a vulnerabilidade foi reproduzida. Um erro de importação, uma falha de build, uma dependência ausente e uma asserção de segurança falha todos saem com diferente de zero e são indistinguíveis para o executor. Toda verificação exploit e variant deve imprimir e liberar PPV_REACHED imediatamente antes de avaliar sua asserção, em ambas as revisões:

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

O token também está no ambiente como PPV_REACHED_MARKER. Ele deve ir para o stdout, como uma linha própria. Stderr não é escaneado, porque um traceback SyntaxError do Python ecoa a fonte ofensora e, de outra forma, satisfaria a verificação para um harness que não executou nada. Uma execução sem ele deixa uma lacuna marker_missing. Achados independentes de outras verificações permanecem no resultado. Libere explicitamente: um harness cujo payload causa segfault ou chama _exit perde a saída em buffer e perde sua própria evidência.

Essas verificações também são executadas cegas para o lado. {side} não é expandido para elas, PPV_SIDE está ausente em seu ambiente, o diretório de checkout é nomeado aleatoriamente, e o validador do plano rejeita qualquer verificação exploit ou variant cujo argv ou env mencione qualquer um deles. Uma asserção que pode ver em qual revisão está pode fazer asserções nessa em vez de no código, que é a maneira mais barata possível de fingir uma reprodução seguida de uma correção.

Ambiente

As verificações são executadas sob um ambiente mínimo fixo: PATH, HOME e um punhado de chaves temporárias/de usuário, mais LANG/LC_ALL=C, TZ=UTC, PYTHONHASHSEED=0, NO_COLOR, TERM=dumb. Todo o resto no ambiente do chamador é descartado. Toolchains que precisam de mais obtêm isso explicitamente:

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

Nomes e valores encaminhados são registrados em result.json. Uma variável solicitada que não está definida é um erro, não uma string vazia. Duas classes são recusadas imediatamente: nomes que são lidos como credenciais (*SECRET*, *TOKEN*, *API_KEY*, …), porque o valor seria escrito no resultado; e nomes que mudam o que é executado (LD_PRELOAD, BASH_ENV, NODE_OPTIONS, GIT_SSH_COMMAND, …), porque essas variáveis podem alterar qual código é executado. As variáveis fixas do executor e todo nome PPV_* também são reservados e não podem ser encaminhados.

Substituidores expandidos em argv e valores env por verificação: {checkout} (a revisão em teste), {plan_dir} (uma cópia isolada dos artefatos do plano para aquela invocação), {scratch} (um diretório opaco novo para aquela invocação de verificação) e {side} (base ou patched, e não disponível para verificações exploit/variant). Os mesmos valores chegam como PPV_CHECKOUT, PPV_PLAN_DIR, PPV_SCRATCH, PPV_SIDE e PPV_CASE_ID. Escreva apenas sob {scratch}; o caminho do diretório de evidências não é passado para as verificações. As invocações de base e patch não compartilham raízes de scratch, plano ou árvore de trabalho gerenciadas pelo executor. Após cada invocação sair, seu diretório scratch é arquivado sob o caminho determinístico results/scratch/<check-id-and-side>, sua cópia privada do plano é descartada, e todo elemento argv legível que resolve para um arquivo é hashado em argv_files. Arquivos dentro das raízes de plano ou checkout isoladas são adicionalmente retidos sob results/helpers/<sha256> até 16 MiB; o registro explica por que qualquer outro arquivo não foi arquivado. Use um diretório dedicado para plan.json: seus arquivos e diretórios irmãos são copiados para cada invocação {plan_dir}. Mantenha o código auxiliar sob o diretório checks/ desse diretório ou verificado no repositório alvo para que seus bytes sejam revisáveis. O plano de máquina contendo pinos de commit, o diretório de saída atual e árvores de resultado anteriores detectadas são excluídos; symlinks são rejeitados. O snapshot limpo permanece apenas na memória do executor, e os lados de exploração/variante são executados em ordem aleatória enquanto os nomes dos arquivos de evidência permanecem determinísticos. Stdout/stderr usam descritores de captura anônimos ou nomeados aleatoriamente e são copiados para os arquivos de evidência nomeados apenas após a saída do processo filho, então a inspeção de fd não pode revelar o rótulo do lado.

Este isolamento não é uma sandbox de host: as verificações são executadas com os privilégios do chamador e um auxiliar malicioso poderia usar estado externo arbitrário ou inferir deliberadamente a revisão a partir da fonte ou metadados Git. Inspecione os artefatos auxiliares endereçados por conteúdo e use uma sandbox de SO/contêiner quando o código de verificação em si não for confiável.

As árvores de trabalho de validação ativas são bloqueadas pelo Git com tokens de proprietário aleatórios apoiados por bloqueios de arquivo do kernel, então outro validador concorrente não pode podá-las e a reutilização de PID não pode se passar por um proprietário. Se o executor for morto à força, a próxima execução desbloqueia registros de proprietário obsoletos. Para recuperação manual, inspecione git worktree list, então use git worktree unlock <path> e git worktree remove --force <path> (ou git worktree prune após o caminho ter sumido).

Leia evidence-model.md ao projetar cobertura, selecionar variantes ou interpretar achados e lacunas de validação. Não o leia para execução de CLI de rotina.

Regras de Cobertura

  • Derive variantes da causa raiz, não mutações cosméticas da carga original.
  • Enumere locais de chamada irmãos, callbacks/saídas alternativas, caminhos de erro, teardown, propriedade, serialização e valores de limite tocados pela correção.
  • Faça cada teste de exploração ou variante afirmar o comportamento seguro. Ele deve falhar na base vulnerável; um teste que passa em ambas as revisões não prova nada sobre a correção. Leia o stderr do lado base e confirme que a falha é a asserção que você escreveu, não um harness que nunca chegou lá.
  • Mantenha as asserções de exploração e variante limitadas ao invariante de segurança. Teste vivacidade, tipos/mensagens de erro exatos, tempo e compatibilidade separadamente como verificações behavior ou regression; caso contrário, uma alteração de contrato não relacionada pode se passar por prova de que a vulnerabilidade permanece.
  • Mantenha o harness control benigno e faça-o exercitar o componente alterado. Ele estabelece que o harness funciona em ambas as revisões. Controles falhos deixam lacunas e impedem atribuir outras falhas ao patch. As observações brutas permanecem disponíveis para revisão.
  • Use behavior apenas para comportamento que deve permanecer inalterado. A comparação exata de saída é deliberada; mova valores instáveis para trás de um harness de teste determinístico em vez de normalizá-los em prosa.
  • Faça as verificações security passarem na base vulnerável antes de tratar uma falha corrigida como recém- introduzida. Uma linha de base falha deixa atribuição não resolvida.
  • Não edite o patch durante a validação. Retorne falhas ao autor do patch e inicie uma nova execução recém-fixada.

Lendo o Resultado

O esquema result.json 2.0 contém uma assessment com status, findings, gaps e human_review_required. O status é complete quando todas as verificações necessárias produziram evidências utilizáveis, mesmo que algumas verificações tenham encontrado falhas. O status é incomplete quando qualquer lacuna permanece. Findings nomeiam o ID da verificação, o tipo de verificação e a expectativa falha. Gaps nomeiam o ID da verificação e a evidência ausente, com um ID de verificação nulo para problemas de nível de execução, como falhas de limpeza.

Verificações de suíte são executadas na revisão corrigida primeiro. Uma falha completa aciona a mesma verificação na linha de base. Se a linha de base passar, reporte a falha após o patch. Se ambas falharem, preserve ambos os logs e reporte que a atribuição não está resolvida. Não presuma que códigos de saída correspondentes significam a mesma falha.

O executor sai com 0 para verificações completas sem achados, 1 para verificações completas com achados, 10 para validação incompleta e 64 para entradas inválidas. Leia o artefato mesmo após saída 10: ele pode conter achados suportados junto com lacunas. Evidências de fonte ou build não podem estabelecer comportamento em tempo de execução. Declare o nível de evidência junto com qualquer resultado de aprovação.

Fluxo de Trabalho Dinâmico do Claude

O Claude Code expõe o fluxo de trabalho empacotado como /post-patch-validation:validate-patch. Para passar entradas estruturadas através da ferramenta Workflow, use o nome sem a barra inicial:

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

Use patchFile em vez de patchRef quando apropriado. O fluxo de trabalho usa lentes de cobertura fixas para propor verificações e um executor fixo para executar esta skill. Agentes podem escrever artefatos de teste. O executor Python registra achados e lacunas, e revisores reportam cobertura ou evidência preocupações separadamente. NEEDS_REPAIR retorna falhas suportadas mesmo quando outras verificações deixaram lacunas. BLOCKED significa que a evidência está incompleta sem uma falha suportada. Verificações de aprovação avançam para READY_FOR_HUMAN_REVIEW apenas após ambas as revisões de evidência aprovarem, caso contrário REVIEW_REQUIRED. O fluxo de trabalho não pode fazer perguntas após o lançamento, então passe toda entrada antecipadamente.

Racionalizações a Rejeitar

| Racionalização | Correção requerida [...]

[...truncado para tradução]

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.

Habilidades Relacionadas