
Encontre a vulnerabilidade que seus testes nunca foram escritos para detectar. Uma demonstração ReGrade modelando CVE-2023-5968: detecte um vazamento de hash de senha comparando um aplicativo consigo mesmo.
Uma demonstração prática de descoberta de zero-day com ReGrade. Você apontará um conjunto de testes comum para o ReGrade, gravará contra um pequeno serviço, reproduzirá contra uma segunda cópia do mesmo serviço e usará Claude Code + as ferramentas MCP do ReGrade para revelar um vazamento de hash de senha — uma vulnerabilidade que nenhum teste foi escrito para encontrar.
Ele modela um bug real: CVE-2023-5968, onde o endpoint de atualização de nome de usuário de uma plataforma de colaboração retornava o objeto completo do usuário incluindo o hash bcrypt da senha. Ele foi lançado em 2017 e sobreviveu a 7 anos de testes, revisões e auditorias. (Artigo da Curtail.)
A reviravolta: não há v2. Você compara o aplicativo consigo mesmo. Uma nova instância hasheia suas senhas com diferentes salts bcrypt, então os valores do hash vazado diferem entre as duas cópias — e essa entropia é o que o ReGrade sinaliza. A vulnerabilidade está latente no código que você já enviou; nenhuma mudança de versão é necessária para encontrá-la.
regrade de https://app.regrade.curtail.com/downloads e defina REGRADE_API_KEY (ou ~/.regrade/key).claude plugin marketplace add https://app.regrade.curtail.com/downloads/latest/marketplace.json depois claude plugin install regrade@regrade --scope user e conecte-o uma vez (/mcp, logado na mesma conta da sua chave).Uma pequena API de "chat de equipe" (app/store.py) com usuários e canais. O Docker Compose executa duas cópias idênticas — mesma imagem, mesmo código, sem flag de versão:
http://localhost:8001 — você grava contra esta.http://localhost:8002 — você reproduz contra esta.Um endpoint tem uma falha plantada:
| Endpoint | Comportamento |
|---|---|
GET /users/<id> | Sanitizado — nunca retorna a senha. A linha de base limpa. |
As senhas são hasheadas com bcrypt na inicialização, então a instância-a e a instância-b possuem hashes diferentes para o mesmo usuário.
git clone https://github.com/Curtail-Inc/hello-ReGrade-security
cd hello-ReGrade-security
docker compose up -d --build
traffic/test_api.py é um conjunto normal de testes funcionais: login, ler um usuário, renomear um usuário, listar canais. Ele afirma o comportamento CRUD e não faz nenhuma afirmação de segurança — nunca verifica se password vaza. (Por que faria? Ninguém sabia que o bug existia.)
Inicie o proxy do sensor na frente da instância-a:
regrade proxy --target http://localhost:8001 --port 19870
Em outro terminal, execute o mesmo conjunto de testes — apenas aponte BASE_URL para o proxy. Esta é a única mudança:
BASE_URL=http://localhost:19870 python -m pytest traffic/test_api.py
Todos os testes passam, inalterados. Pare o proxy (Ctrl-C); a gravação faz upload e imprime um Recording ID: <uuid> — anote-o.
regrade replay --rec-id <RECORDING_ID> --target http://localhost:8002
Mesmo código em ambos os lados — as únicas diferenças são os valores que uma nova instância gera.
Abra este repositório no Claude Code e peça para ele te guiar pela reprodução. Guiado pelo CLAUDE.md deste repositório, ele irá:
summarize_deltas → vários deltas: o token de login, timestamps created_at do canal e — silenciosamente entre eles — $.password.create_id_mapping para o $.token da sessão (um ID dinâmico, não ruído para descartar),create_filter_rule DROP para $.channels[*].created_at (um timestamp por inicialização),apply_profile_to_replay, então query_deltas(unlabeled_only=true) — repita até que apenas um delta permaneça.$.password — um hash bcrypt no corpo da resposta. Um vazamento classe CVE, encontrado com zero conhecimento prévio e zero afirmações de segurança.O token de sessão e o hash da senha ambos diferem entre as duas execuções — ambos são strings de alta entropia que mudam a cada vez. Um é ruído legítimo que você mapeia; o outro é uma violação. Você não pode distingui-los por "mudou" — você tem que olhar para o que mudou. Filtrar todo campo de alta entropia como ruído e você teria escondido a vulnerabilidade.
Essa é a lição: o ReGrade não valida expectativas, ele compara comportamento — então pode revelar os bugs que ninguém pensou em escrever um teste para.
app/store.py é um arquivo. Os caminhos GET chamam sanitize(); o caminho PATCH esquece de chamar. Olhe depois de encontrá-lo com o ReGrade — o ponto é que o ReGrade o pegou a partir apenas do tráfego, comparando o aplicativo consigo mesmo.
Apache-2.0.
PATCH /users/<id> (renomear) | O bug — retorna o objeto completo do usuário incluindo o hash bcrypt de password. Uma chamada sanitize() ausente, exatamente como CVE-2023-5968. |