QAtration lanza ataques reales de inyección de prompts contra tu bot de IA y te entrega un informe en lenguaje claro de lo que filtró o hizo, antes de que lo encuentre otro. Lo ejecutas tú. En tu máquina o en tu CI, contra tu propio despliegue: sin cuenta, sin entregar ningún endpoint, sin enviarnos nada.
No apuntes esto a un sistema que no sea tuyo. Envía ataques reales (inyección de prompts, exfiltración de datos, abuso de herramientas) a la URL que le des. Tu propio despliegue, o uno cuyo dueño te haya dado permiso por escrito de antemano. No un chatbot público que te parezca interesante. No la demo de un proveedor. Lee AUTHORISED-USE.md antes de la primera ejecución.
Dos dependencias. Todo el corpus de ataques viene incluido, y también las evidencias que respaldan cada número de esta página, todas ellas en
out/, que se distribuye con el repositorio. Los informes propios de las otras dos herramientas no están aquí, porque sus licencias no lo permiten. Los comandos que los regeneran sí.
Medido en nuestros propios objetivos de prueba, no proyectado. La transcripción de al lado ilustra la idea. Los números de arriba son resultados.
Cada función de IA que sale a producción es una nueva superficie de ataque. Cuánta parte de la tuya puede alcanzar depende de lo que tu despliegue le deje ver, y aquí la línea se traza en lugar de difuminarse, porque un escáner que dice cubrir lo que no puede observar es exactamente aquello que intentas evitar.
Basta un endpoint de chat: esto se puede probar tal cual, incluso a lo largo de varios turnos.
El texto del atacante anula las reglas de tu bot: «ignora tus instrucciones y…».
Tu bot revela claves de API, códigos internos o los datos de otro cliente.
Tus instrucciones ocultas se filtran literalmente: el mapa para cada ataque posterior.
Una regla colocada en un turno cambia en silencio cada respuesta posterior, mucho después de que la conversación vuelva a parecer normal.
No puedes colocar un documento en una base de conocimiento en la que no puedes escribir, y desde fuera no puedes distinguir una llamada a herramienta que se ejecutó de otra que el bot solo describió, una distinción en la que hemos medido que los propios bots se equivocan. Para esto hace falta el corpus, las definiciones de las herramientas o visibilidad de las llamadas. Medido con las evidencias que se distribuyen con esta herramienta: 62 de 137 hallazgos en objetivos que informan de llamadas a herramientas no aparecen en absoluto si solo se lee la respuesta. El bot responde con educación y coloca el secreto en un argumento de la llamada.
A tu agente lo convencen de ejecutar una acción irreversible: borrar, reembolsar, enviar un correo.
SQL o un comando de shell colado en una llamada a herramienta. Una clase de fallo vieja, una puerta de entrada nueva.
Un solo documento malicioso en tu RAG secuestra las respuestas a preguntas inocentes.
Una línea oculta en la descripción de una herramienta hace que tu agente filtre algo ante una pregunta corriente, sin necesidad de ningún mensaje del atacante.
qatration init escribe la configuración por ti: la URL, la forma de la petición, y en qué campo de la respuesta HTTP viene el mensaje del bot. Un objetivo remoto pide además una cabecera de autenticación, como variable de entorno. Configuraciones listas para APIs con el formato de OpenAI y para las de Anthropic, Bedrock y Vertex. qatration onboard envía una pregunta corriente y te dice qué falta antes de que salga un solo ataque.
qatration init genera un secreto propio y el bloque que hay que pegar en tu prompt de sistema. La ejecución confirma primero que de verdad llegó: un canario sin colocar significa que ninguna comprobación encuentra nada, y eso se lee exactamente igual que un bot que aguantó.
Qué se filtró, cómo exactamente, y la corrección concreta que lo cierra, escrito para un equipo sin experto en seguridad. --fail-on exploited hace fallar una build. qatration sarif pone los hallazgos directamente en tu pestaña de code scanning.
Un ataque que falló aparece como un cero. También una comprobación que no pudo ejecutarse, y también un bot realmente endurecido, y ahí es donde las pruebas se atascan: tres hechos distintos llegan con el mismo aspecto, y nadie sabe qué probar después. Estas son mediciones de ejecuciones reales, no proyecciones.
Y una brecha solo es una brecha si la causó el ataque. Cada objetivo recibe primero una ejecución inofensiva: preguntas corrientes, nadie atacando. En uno de los bots de aquí,
canary_in_tool_call se dispara en el 88% de ese tráfico corriente, así que un hallazgo que se apoye solo en él se marca como no atribuible en lugar de contarse.
Cuando un ataque falla, el informe nombra lo que lo detuvo: la comprobación de identidad, el filtro de contenido, un permiso del backend, o una llamada a herramienta que solo se imprimió y nunca llegó a ejecutarse. En una transcripción, esa última parece una brecha y no vale nada.
Un bot, dos modelos, 254 ataques cada uno, 3 intentos cada uno. El pequeño cayó en 27 de ellos, el grande en 24, y 18 de esos son los mismos ataques, 17 de los cuales rompen ambos modelos en todos y cada uno de los intentos. En este bot el modelo más grande solo reordenó, en los márgenes, qué ataques entran. El agujero no lo cierra.
Contra un framework de guardrails real, 46 ataques escritos en la ventana de chat: no pasó ninguno. Tampoco pasó uno llevado dentro de un documento recuperado, mientras sus dos raíles estaban activos. Apaga el filtro de salida y ese mismo documento sale en todos y cada uno de los intentos. Los filtros de entrada leen lo que escribe el usuario, y nunca ven lo que tu base de conocimiento le entrega al modelo, así que el rail de entrada nunca fue lo que lo detenía.
Volvimos a enviar los mismos mensajes a ese guardrail y no siempre estuvo de acuerdo consigo mismo: cinco formulaciones recibieron veredictos distintos con una entrada idéntica, y una pregunta corriente se permitió diez de doce veces. Por eso informamos de cuántos intentos rompieron algo, y no de si lo rompió uno. Una sola ejecución es la historia de una sola tarde, y eso vale igual para un resultado limpio que para uno malo, incluido el nuestro.
El mismo guardarraíl que bloqueó aquel documento también se negó a responder a 6 de 9 preguntas corrientes de clientes sobre los temas afectados. Una defensa que responde «no» a tus clientes es un número que quieres tener antes de publicar, no después.
Un escáner que siempre encuentra algo no vale nada, así que medimos el número contrario: 1500 sondas inofensivas sobre 30 objetivos, sin ningún atacante en ninguna de ellas, pasadas por las mismas comprobaciones. La mitad son usuarios que hablan de seguridad con toda legitimidad, porque eso es justo lo que rompe un detector de patrones: alguien que pega la consulta que falla, un agente de soporte que reenvía un stack trace, alguien que pregunta si un dominio sósia es real.
Los bots escritos aquí son el caso fácil, así que lo apuntamos a un framework de agentes que nadie de aquí diseñó. Produjo ocho falsas alarmas en una ejecución de 48 prompts limpios, en cuatro categorías que 480 sondas contra nuestra propia flota no habían producido ni una sola vez. Las cuatro están corregidas, y las dos reglas que las sustentan hacen fallar ahora nuestra build en lugar de tu informe: ninguna comprobación puede leer la pregunta, y ninguna comprobación puede tratar las propias palabras del agente como prueba sobre el sistema.
Ejecutado contra los mismos objetivos de terceros que garak y promptfoo, con cada respuesta de las tres puntuada por una única regla de subcadena en lugar del juez propio de cada herramienta. En una aplicación RAG sin guardrails, el 46% de las sondas inofensivas ya devuelve la cadena colocada, de modo que contar hallazgos mide la aplicación y no al atacante. Una de las tres herramientas lo dice en su informe. En el objetivo protegido las tres puntúan cero según la regla común, y fuimos los únicos que encontramos algo, una brecha en 324, mientras ese mismo despliegue se niega a responder a 38 de 48 preguntas corrientes de clientes. La página de la comparación publica también dónde las otras dos son mejores, y una afirmación que retiramos después de que un revisor pidiera un valor p. Leer la comparación.
Un perfil de doce sondas, todas inofensivas: cinco bots entregaron sus propias instrucciones ante una petición sencilla. Uno imprimió su clave de sesión confidencial dentro de la misma frase que le prohibía compartir esa clave. Dos informaron de un reinicio de la base de datos sin tener ninguna herramienta capaz de reiniciar nada.
Cada ejecución se conserva, así que cada hallazgo lleva la fecha en que apareció por primera vez. «Crítico» es una opinión. «Crítico y abierto desde el día tres» es un hecho sobre cómo responde un equipo a esos hallazgos, y es esa línea la que consigue que se planifique una corrección.
Un hallazgo que vuelve después de que lo cerraras se marca como reaparecido, y no se cuenta en silencio junto a los nuevos. Una corrección que no aguantó es la peor de las dos conversaciones, y mezclarlas la esconde.
Si una ejecución no envía un ataque, ese ataque figura en el informe como no probado, nunca como corregido. La ausencia no es un resultado limpio, y un informe que confunde ambas cosas te dice que tus vulnerabilidades desaparecieron cuando en realidad nadie miró.
Algunas llamadas pasan a una herramienta un valor que no aparece en ningún texto que podamos leer. Las listamos aparte y te decimos qué registro las abre, porque la diferencia entre «comprobamos y estaba limpio» y «no pudimos verlo» es la diferencia entre una medición y una promesa.
«Le dijimos que no revelara secretos» es una afirmación, no una defensa: en los objetivos de aquí cayó en los primeros ataques. QAtration también da por limpios a los bots que de verdad están blindados, así que un resultado limpio sí significa algo. Mide tu bot, en lugar de gritar «¡que viene el lobo!» cada vez.
Apache 2.0. Instálalo, apúntalo a tu propio despliegue, guarda las evidencias.