Langroid SQLChatAgent: de la inyección prompt-a-SQL a la RCE (CVE-2026-25879)
Divulgada el 1 de junio de 2026, la CVE-2026-25879 (CVSS 9.8) permite que un agente SQL víctima de inyección de prompt ejecute primitivas como COPY FROM PROGRAM, convirtiendo un chatbot en ejecución de código en el host de la base de datos.
¿Qué es esto?
El 1 de junio de 2026 se publicó la CVE-2026-25879 para Langroid, un framework de Python para construir aplicaciones impulsadas por LLM. El aviso (GHSA-mxfr-6hcw-j9rq, revisado por GitHub el 27 de mayo de 2026) califica el problema como 9.8 Crítico (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) y lo asocia a las debilidades CWE-89 (inyección SQL) y CWE-94 (inyección de código).
El componente afectado es SQLChatAgent, un agente integrado que permite hacer preguntas en lenguaje natural sobre una base de datos. El agente pide a un LLM que traduzca la pregunta a SQL y luego ejecuta ese SQL. Como el SQL lo produce un modelo que puede manipularse mediante inyección de prompt, un atacante capaz de moldear la entrada del agente —de forma directa, o indirecta a través de datos que el agente vuelve a leer de la base— puede lograr que el agente emita y ejecute consultas que el operador nunca previó. Las versiones anteriores a la 0.63.0 son vulnerables.
Cómo funciona
La causa raíz es una frontera de confianza que no existe: la salida del modelo se ejecuta como un comando privilegiado, sin ninguna lista blanca entre la generación y la ejecución. El SQL generado por el LLM pasa directamente al controlador de la base de datos (run_query en sql_chat_agent.py, según la traza de llamadas del aviso): todo lo que se pueda convencer al modelo de escribir, la base intentará ejecutarlo.
La escalada de la «simple inyección SQL» a la «ejecución remota de código» proviene del rol de la base de datos, no de Langroid en sí. Cuando la conexión usa un rol con privilegios de ejecución de código o acceso al sistema de archivos, el SQL ordinario se convierte en una shell:
PostgreSQL : COPY ... FROM PROGRAM '<command>' (needs pg_execute_server_program / superuser)
MySQL : SELECT ... INTO OUTFILE / LOAD_FILE (needs FILE privilege)
MSSQL : EXEC xp_cmdshell '<command>' (needs xp_cmdshell enabled)
Estas primitivas son funciones de DBA documentadas desde hace tiempo, no un nuevo instrumental de ataque. La novedad está en la vía de entrega: en lugar de una inyección web clásica a través de un campo parametrizado, el «punto de inyección» es un prompt conversacional, y lo que se engaña es un modelo de lenguaje. La prueba de concepto pública presenta una instrucción maliciosa como una «prueba de integración» inofensiva y oculta la consulta objetivo tras un paso de codificación, de modo que la petición parezca un simple trabajo de decodificación y no un comando evidente. Deliberadamente no reproducimos aquí el payload funcional; lo que importa para la defensa es el mecanismo, y la PoC del autor ejecuta id mediante COPY ... FROM PROGRAM solo para demostrar que la primitiva se dispara.
Es la tercera RCE del mismo framework que sigue un mismo patrón: una herramienta de agente ejecuta código controlado por el modelo contra un backend potente. Fue precedida por la CVE-2025-46724 (inyección de código pandas_eval en TableChatAgent) y su elusión de WAF de febrero de 2026, la CVE-2026-25481 (9.4 Crítico). Las listas de bloqueo se eludieron; la variante SQL solo trasladó el mismo problema a la capa de base de datos.
Por qué importa
Una función de «chatea con tu base de datos» en solo lectura es justo el tipo de integración que los equipos despliegan sin modelo de amenazas, porque parece de solo lectura. La CVE-2026-25879 demuestra lo contrario: con AV:N/AC:L/PR:N/UI:N, un actor remoto no autenticado capaz de alcanzar la entrada del agente —un chatbot de soporte, un pipeline RAG que ingiere documentos controlados por el atacante, un asistente de tickets— puede alcanzar la shell del host de la base si la conexión tiene privilegios excesivos.
La vía indirecta es la más peligrosa. Incluso cuando los usuarios finales son de confianza, cualquier dato que el agente vuelva a leer puede portar instrucciones. Una fila envenenada, un PDF manipulado, un campo de comentario o una página web extraída que el agente luego resume pueden convertirse en el vector de inyección: la superficie de ataque pasa a ser todo el corpus que el agente toca, no solo el cuadro de chat.
La recurrencia en tres CVE es la verdadera lección. El defecto es arquitectónico: mientras un framework deje que la salida de un LLM llegue a un eval, a una shell o a una sesión SQL privilegiada sin un cierre estricto, parchear una herramienta solo reubica el fallo. Quien construya agentes que ejecutan código o consultas generados por un modelo debe asumir que hereda esta clase de problema, no solo esta CVE.
Defensas
- Actualice a Langroid 0.63.0 o superior. La corrección hace que
SQLChatAgentpase por defecto a una lista blanca de sentencias analizadas consqlglot, limitada a SELECT, con una lista de bloqueo de patrones peligrosos sensible al dialecto. El comportamiento anterior solo vuelve si establece explícitamenteallow_dangerous_operations=True— déjelo desactivado salvo en despliegues plenamente confiables. - Aplique el mínimo privilegio al rol de la base. Es el control que rompe la RCE con independencia de los fallos del framework. Asigne al agente un rol dedicado de solo lectura; revoque
FILE(MySQL), manténgalo fuera del superusuario de PostgreSQL /pg_execute_server_program, y asegúrese de quexp_cmdshellesté deshabilitado (MSSQL). En esta CVE, la RCE depende por completo de los privilegios del rol. - Valide el SQL generado antes de ejecutarlo. Analice la salida del modelo con un parser SQL real, permita solo los tipos de sentencia previstos y rechace verbos DDL/administrativos (
COPY ... FROM PROGRAM,CREATE FUNCTION,INTO OUTFILE,EXEC). Nunca pase texto del LLM a un controlador sin analizarlo. - Aísle el backend. Ejecute la base de datos (y cualquier herramienta de ejecución de código) en un segmento de red sin acceso saliente ni credenciales para pivotar, de modo que una inyección exitosa quede en un radio de impacto contenido.
- Trate los datos ingeridos como entrada no confiable. Para agentes RAG y con herramientas, el canal indirecto es lo que más importa: sanee y acote el contenido recuperado, y no permita que documentos resumidos disparen acciones privilegiadas sin validación humana.
- Registre y audite las llamadas a herramientas. Guarde el SQL exacto que ejecuta cada turno del agente. Las sentencias con
PROGRAM,OUTFILE,xp_cmdshello DDL inesperado son alertas de alta señal.
Estado
| Elemento | Referencia | Fecha | Notas |
|---|---|---|---|
| Aviso GHSA | GHSA-mxfr-6hcw-j9rq | 2026-05-27 | Revisado por GitHub, prompt-a-SQL → RCE en SQLChatAgent |
| Publicación de la CVE | NVD / CVE | 2026-06-01 | CVSS 9.8, CWE-89 + CWE-94 |
| Versiones afectadas | langroid | < 0.63.0 | RCE cuando el rol de la BD permite primitivas de código/archivo |
| Versión corregida | langroid | 0.63.0 | Lista blanca SELECT; opt-out vía allow_dangerous_operations |
| RCE relacionadas previas | CVE-2025-46724 / CVE-2026-25481 | 2025 → feb. 2026 | Inyección pandas_eval + elusión de WAF en TableChatAgent |
El titular no es «un LLM escribió SQL malo». Es que un agente conversacional con una conexión privilegiada a una base de datos es una shell remota esperando la frase adecuada — y la corrección que aguanta es el mínimo privilegio más un parser entre la generación y la ejecución, no un prompt más astuto.