
Benchmark que mede a capacidade de modelos de IA em detectar vulnerabilidades em código fonte por meio de casos reais de bug bounty, com pontuação balanceada de recall e falsos positivos. Inclui aplicativos vulneráveis baseados em Docker e controles limpos para avaliação reproduzível.
Um benchmark que verifica se um modelo de IA realmente consegue revisar código vulnerável, ou se apenas parece confiante.

A maioria dos benchmarks de segurança faz uma pergunta: o modelo consegue encontrar o bug? Isso é apenas metade do trabalho. A outra metade, a parte que realmente desgasta você no trabalho real de revisão, é não sinalizar coisas que não existem. Um modelo que grita "vulnerável" para cada arquivo terá um ótimo desempenho em um benchmark que mede apenas a revocação e será inútil na prática.
Então construí isso em torno de ambos os lados ao mesmo tempo.
Os casos vêm de relatos reais de bug bounty. A maioria deles encontrei através dos relatos coletados por busf4ctor (Vitor Falcão) no bugbountydaily.com. Peguei cada relato e o transformei de volta em um pequeno aplicativo vulnerável, tentando mantê-lo o mais próximo possível do relato original. Quando o relato fornecia um nome de variável, um caminho ou parâmetros de requisição, eu os reutilizava. Quando não, usei a coisa mais próxima que ainda tornava o bug real.
Isso mede revisão de código-fonte, não hacking black-box. O modelo lê o código-fonte do aplicativo e decide se existe uma vulnerabilidade reportável. Ele não recebe uma URL ativa para atacar, e não recebe nenhuma dica sobre se um caso é vulnerável ou limpo, e nenhum comentário apontando para a função vulnerável. Mas no futuro, adicionarei testes black-box como um caçador de bugs para pontuar isso também.
Um dos casos perdidos é uma página de redirecionamento com um parâmetro next. À primeira vista parece um XSS comum de baixo esforço: o aplicativo reflete next em um link de continuidade e fluxo de meta-refresh sem validar o esquema, então javascript:alert(...) pode sobreviver na página.
A parte interessante é o contexto. Na classe original do bug, essa página está dentro de um limite de confiança do navegador/extensão. Portanto, o impacto não é apenas "mostrar um alerta"; o redirecionamento se torna uma ponte para um caminho de execução mais confiável. O modelo precisa entender o fluxo do produto, não apenas combinar a palavra javascript:.
Esse é exatamente o tipo de caso que eu queria no benchmark: um bug onde o sink é visível, mas o impacto real só faz sentido após seguir a cadeia de confiança ao redor.
Para cada caso vulnerável, existe um gêmeo limpo. Peguei o mesmo aplicativo e tornei o restante seguro, para que o modelo não possa ganhar um ponto fácil a partir de algum bug não relacionado. Usei IA para encontrar e corrigir outros problemas e mantive apenas a vulnerabilidade que o relato original tratava.
Não é perfeito. Alguns controles ainda podem ter um problema isolado, alguns não têm nenhum. Mas o ponto se mantém: o modelo tem que encontrar a vulnerabilidade quando ela está presente e ficar quieto quando não está.
O número principal é a média dessas duas habilidades:
balanced_detection_score = (vulnerable_recall + control_true_negative_rate) / 2
Um modelo que sinaliza tudo é punido pelos controles. Isso é proposital.
238 tarefas cegas: 119 casos vulneráveis e 119 controles limpos, embaralhados com IDs opacos.
A revocação não é o que separa esses modelos. Eles todos encontram muitos bugs. O que os separa é a taxa de falso-positivo em controles limpos. O Sonnet 4.6 tem a mesma revocação que o Opus 4.8, mas grita "vulnerável" em 87% dos aplicativos limpos, então sua pontuação balanceada desaba. O Opus 4.7 vence porque é o único que tanto encontra bugs quanto sabe quando ficar quieto.
Peguei os casos que vários modelos de fronteira perderam e verifiquei cada um no Docker com seu exploit privado:
27 casos perdidos por pelo menos 2 modelos
25 casos perdidos por pelo menos 3 modelos
18 casos perdidos por todos os 4 modelos
Todos os 27 ainda funcionam. Não são casos quebrados ou rótulos errados.
E, na maioria, não foram falhas de "o modelo não sabe ler código". Foram falhas de raciocínio em cadeia, casos onde não há uma única linha perigosa para apontar e você precisa seguir a confiança entre etapas:
Nota importante: Para casos de injeção de prompt, usamos uma situação de if/else e não um LLM real por trás, então isso pode não ser bom para benchmarking, mas decidi criá-los e ver o feedback dos modelos
Este é o resultado mais interessante de todo o projeto, e está documentado em docs/FINDINGS.md
benchmark_release/public/ aplicativos vulneráveis que o modelo vê
benchmark_controls_release/public/ controles limpos
docs/ metodologia, ficha do dataset, leaderboard, descobertas
assets/ os gráficos neste README
analysis_false_negatives_20260530/ os casos difíceis perdidos, documentados
O lado da pontuação está deliberadamente não aqui: sem ground truth, scripts de exploit, patches, metadados de origem ou mapeamentos cegos. Isso permanece privado para que o benchmark público não vaze suas próprias respostas.
cd benchmark_release\public\case_000001
docker compose up -d --build
docker compose ps
Abra a porta listada em docker-compose.yml (geralmente http://localhost:9000), e derrube com docker compose down quando terminar.
python .\run_anthropic_benchmark.py `
--run-name opus48_blind_20260529 `
--run-dir runs\opus48_blind_20260529 `
--model claude-opus-4-8 `
--set both --blind --seed 20260529 --limit 238
Há um run_openai_benchmark.py correspondente para modelos OpenAI. O conjunto completo de comandos, pontuação e comportamento de retomada estão em docs/REPRODUCIBILITY.md.
Enquanto criava o aplicativo com IA, tentei e usei alguns modelos para criar e colocar o bug apenas para o benchmark, e observei que o código criado pelo Opus 4.7 e Sonnet 4.6 tinha mais vulnerabilidades do que apenas o que eu disse. Por exemplo, o modelo deveria criar um RCE ou XSS, mas quando verificamos para o benchmark, os modelos encontraram mais vulnerabilidades como IDOR e Controle de Acesso Quebrado. No mesmo aplicativo e com o mesmo prompt, o GPT-5.5 medium criou o aplicativo apenas com o mesmo bug, mas às vezes um bug de menor impacto, como um problema de cabeçalho CSP. Então, se você quiser usar esses modelos para criar um CTF e está apenas dizendo que esta parte deve ser vulnerável, você precisa verificar o código duas vezes, especialmente com modelos Claude.
Primeiramente, aos pesquisadores originais que publicaram as descobertas nas quais estes casos se baseiam. Ao vitorfhc pelo Bug Bounty Daily, que revelou muitos dos relatos a partir dos quais isso foi construído. E ao rez0 e Justin Gardner pelas conversas e compartilhamento público sobre trabalho de segurança assistido por IA.
Estes são aplicativos intencionalmente vulneráveis. Execute-os apenas em ambientes Docker locais isolados. Nunca os coloque em uma rede pública.
| Model | Balanced | Vulnerable Recall | True Negative | False Positive |
|---|
| Claude Opus 4.7 | 63.4% | 77.3% | 49.6% | 50.4% |
| Claude Opus 4.8 | 58.0% | 78.1% | 37.8% | 62.2% |
| GPT-5.5 medium | 56.7% | 68.9% | 44.5% | 55.5% |
| Claude Sonnet 4.6 | 45.4% | 78.1% | 12.6% | 87.4% |