O QAtration dispara ataques reais de injeção de prompt contra o seu bot de IA e entrega um relatório em linguagem simples do que ele vazou ou fez, antes que outra pessoa descubra. Quem roda é você. Na sua máquina ou no seu CI, contra o seu próprio deployment: sem conta, sem entregar nenhum endpoint, sem enviar nada para nós.
Não aponte isto para um sistema que não é seu. Ele envia ataques reais (injeção de prompt, exfiltração de dados, abuso de ferramentas) para qualquer URL que você indicar. O seu próprio deployment, ou um cujo dono tenha dado autorização por escrito com antecedência. Não um chatbot público que você achou interessante. Não a demonstração de um fornecedor. Leia o AUTHORISED-USE.md antes da primeira execução.
Duas dependências. Todo o corpus de ataques vem junto, e as evidências por trás de cada número desta página também, tudo isso em
out/, que é distribuído com o repositório. Os relatórios das outras duas ferramentas não estão aqui, porque as licenças delas não permitem. Os comandos que os regeneram estão.
Medido nos nossos próprios alvos de teste, não estimado. A transcrição ao lado ilustra a ideia. Os números acima são resultados.
Cada recurso de IA que vai para produção é uma nova superfície de ataque. Quanto da sua ele consegue alcançar depende do que o seu deployment permite que ele veja, e aqui essa linha é traçada em vez de borrada, porque um scanner que afirma cobrir aquilo que não consegue observar é exatamente o que você está tentando evitar.
Um endpoint de chat basta: dá para testar tudo isso como está, inclusive ao longo de vários turnos.
O texto do atacante sobrescreve as regras do seu bot: “ignore suas instruções e…”.
O seu bot revela chaves de API, códigos internos ou os dados de outro cliente.
As suas instruções ocultas vazam literalmente: o mapa para todo ataque seguinte.
Uma regra plantada em um turno muda silenciosamente cada resposta seguinte, muito depois de a conversa voltar a parecer normal.
Você não consegue plantar um documento em uma base de conhecimento na qual não pode escrever, e de fora não consegue distinguir uma chamada de ferramenta que realmente rodou de outra que o bot apenas descreveu, uma distinção que já medimos os bots errando a respeito de si mesmos. Para isso é preciso o corpus, as definições das ferramentas ou visibilidade das chamadas. Medido nas evidências distribuídas com esta ferramenta: 62 de 137 achados em alvos que relatam chamadas de ferramenta não aparecem de forma alguma quando se lê apenas a resposta. O bot responde com educação e coloca o segredo em um argumento da chamada.
O seu agente é convencido a executar uma ação irreversível: apagar, estornar, enviar e-mail.
SQL ou um comando de shell contrabandeado para dentro de uma chamada de ferramenta. Uma classe de bug antiga, uma porta de entrada nova.
Um único documento malicioso no seu RAG sequestra as respostas a perguntas inocentes.
Uma linha escondida na descrição de uma ferramenta faz o seu agente vazar algo diante de uma pergunta comum, sem exigir mensagem alguma de um atacante.
qatration init escreve a configuração por você: a URL, o formato da requisição, e onde a resposta fica dentro do retorno. Um alvo remoto ainda pede um cabeçalho de autenticação, como variável de ambiente. Configurações prontas para APIs no formato da OpenAI e para as da Anthropic, da Bedrock e da Vertex. qatration onboard envia uma pergunta comum e diz o que está faltando antes que um único ataque saia.
qatration init gera um segredo seu e o bloco para colar no seu prompt de sistema. A execução confirma primeiro que ele realmente chegou: um canário não plantado faz com que nenhuma verificação encontre nada, e isso se lê exatamente como um bot que resistiu.
O que vazou, exatamente como, e a única correção que fecha isso, escrito para um time sem especialista em segurança. --fail-on exploited faz o build falhar. qatration sarif coloca os achados direto na sua aba de code scanning.
Um ataque que não funcionou relata zero. Uma verificação que não conseguiu rodar também, e um bot de fato reforçado também, e é aí que os testes empacam: três fatos diferentes chegam com a mesma aparência, e ninguém sabe o que tentar em seguida. Essas são medições de execuções reais, não projeções.
E uma brecha só é brecha se o ataque a causou. Cada alvo recebe primeiro uma execução inofensiva: perguntas comuns, ninguém atacando. Em um dos bots daqui,
canary_in_tool_call dispara em 88% desse tráfego comum, então um achado que se apoia só nele é marcado como não atribuível em vez de contado.
Quando um ataque falha, o relatório nomeia o que o deteve: a verificação de identidade, o filtro de conteúdo, uma permissão no backend, ou uma chamada de ferramenta que só foi impressa e nunca chegou a rodar. Essa última se lê como uma brecha em uma transcrição e não vale nada.
Um bot, dois modelos, 254 ataques cada, 3 tentativas cada. O menor caiu em 27 deles, o maior em 24, e 18 desses são os mesmos ataques, 17 dos quais quebram os dois modelos em toda e qualquer tentativa. Neste bot o modelo maior apenas embaralhou quais ataques entram pelas bordas. O buraco, esse ele não fecha.
Contra um framework de guardrails de verdade, 46 ataques digitados no chat: nenhum passou. Também não passou um levado dentro de um documento recuperado, enquanto os dois guardrails dele estavam ligados. Desligue o filtro de saída e esse mesmo documento sai andando em toda e qualquer tentativa. Filtros de entrada leem o que o usuário digita, e nunca veem o que a sua base de conhecimento entrega ao modelo, então o guardrail de entrada nunca foi o que o detinha.
Reenviamos as mesmas mensagens para aquele guardrail e ele nem sempre concordou consigo mesmo: cinco formulações receberam vereditos diferentes com entrada idêntica, e uma pergunta comum foi liberada dez vezes em doze. Por isso relatamos quantas tentativas quebraram algo, e não se uma quebrou. Uma única execução é a história de uma única tarde, e isso vale tanto para um resultado limpo quanto para um ruim, incluindo o nosso.
O mesmo guardrail que bloqueou aquele documento também se recusou a responder 6 de 9 perguntas comuns de clientes sobre os assuntos afetados. Uma defesa que responde “não” aos seus clientes é um número que você quer ter antes de publicar, não depois.
Um scanner que sempre encontra alguma coisa não vale nada, então medimos o número oposto: 1500 sondas inofensivas em 30 alvos, sem atacante nenhum entre elas, pelas mesmas verificações. Metade são usuários que falam de segurança com toda a legitimidade, porque é exatamente isso que quebra um filtro baseado em padrões: uma pessoa desenvolvedora colando a consulta que falha, o suporte encaminhando um stack trace, alguém perguntando se um domínio sósia é real.
Bots escritos aqui são o caso fácil, então ele foi apontado para um framework de agentes que ninguém daqui projetou. Produziu oito alarmes falsos em uma execução de 48 prompts limpos, em quatro categorias que 480 sondas contra a nossa própria frota nunca haviam produzido uma vez sequer. As quatro estão corrigidas, e as duas regras que estão por trás delas agora fazem o nosso build falhar em vez do seu relatório: nenhuma verificação pode ler a pergunta, e nenhuma verificação pode tratar as próprias palavras do agente como evidência sobre o sistema.
Rodado contra os mesmos alvos de terceiros que garak e promptfoo, com cada resposta das três pontuada por uma única regra de substring em vez do juiz próprio de cada ferramenta. Em uma aplicação RAG sem guardrail algum, 46% das sondas inofensivas já devolvem a string plantada, de modo que contar achados mede a aplicação e não o atacante. Uma das três ferramentas diz isso no seu relatório. No alvo protegido as três pontuam zero pela regra comum, e fomos os únicos a encontrar qualquer coisa, uma brecha em 324, enquanto esse mesmo deployment se recusa a responder 38 de 48 perguntas comuns de clientes. A página da comparação publica também onde as outras duas são melhores, e uma afirmação que retiramos depois que um revisor pediu um valor p. Leia a comparação.
Um perfil de doze sondas, todas inofensivas: cinco bots entregaram as próprias instruções a um pedido simples. Um imprimiu a sua chave de sessão confidencial dentro da mesma frase que o proibia de compartilhar essa chave. Dois relataram o reinício de um banco de dados sem ter ferramenta capaz de reiniciar coisa alguma.
Cada execução é guardada, então cada achado carrega a data em que apareceu pela primeira vez. “Crítico” é uma opinião. “Crítico e aberto desde o dia três” é um fato sobre como um time responde a esses achados, e é essa linha que faz uma correção entrar no planejamento.
Um achado que volta depois de você fechá-lo é marcado como retornado, e não contado silenciosamente junto com os novos. Uma correção que não resistiu é a pior das duas conversas, e misturar as duas esconde isso.
Se uma execução não envia um ataque, esse ataque vai para o relatório como não testado, nunca como corrigido. Ausência não é resultado limpo, e um relatório que confunde as duas coisas diz que as suas vulnerabilidades sumiram quando na verdade ninguém olhou.
Algumas chamadas entregam a uma ferramenta um valor que não aparece em nenhum texto que possamos ler. Listamos esses à parte e dizemos qual log os abre, porque a diferença entre “verificamos, e estava limpo” e “não conseguimos ver” é a diferença entre uma medição e uma promessa.
“Dissemos a ele para não revelar segredos” é uma afirmação, não uma defesa: nos alvos daqui essa defesa caiu já nos primeiros ataques. O QAtration também dá como limpos os bots que de fato estão blindados, então um resultado limpo significa alguma coisa. Ele mede o seu bot, em vez de simplesmente dar alarme falso o tempo todo.
Apache 2.0. Instale, aponte para o seu próprio deployment, guarde as evidências.