Los filtros de metadatos vectoriales son un sumidero de inyección en Spring AI
Spring AI pasaba cadenas de filtro e identificadores de documentos controlados por el usuario directamente al lenguaje de consulta de cada backend, convirtiendo el filtrado RAG en inyección SQL y de consultas en cinco almacenes vectoriales.
¿Qué es esto?
Spring AI es la capa de abstracción oficial del framework Spring para integrar funciones de LLM en aplicaciones Java, y se ha convertido en el estándar de facto para la generación aumentada por recuperación (RAG) en la JVM. Su abstracción de almacén vectorial permite guardar embeddings y luego consultarlos mediante un filtro de metadatos — una pequeña expresión del tipo «devolver solo los documentos donde tenant = X y year > 2024». Entre abril y junio de 2026, Spring publicó una serie de avisos que mostraban que varias de estas integraciones construían la consulta subyacente pegando la entrada del usuario directamente en el lenguaje de consulta nativo del backend. El resultado es un fallo de inyección de manual, resurgido dentro de la pila de IA: el filtro de metadatos, pensado para acotar una búsqueda, se convierte en un canal para ejecutar consultas arbitrarias contra el almacén.
Dos avisos resumen el patrón. El primero, publicado el 27 de abril de 2026, es una inyección SQL en el almacén vectorial Azure Cosmos DB de Spring AI, alcanzable cuando una aplicación pasa valores suministrados por el usuario como identificadores de documentos en la ruta de borrado. El segundo, publicado el 12 de junio de 2026, cubre los almacenes Elasticsearch, OpenSearch y GemFire, donde caracteres especiales en una cadena de filtro podían forzar la ejecución de consultas arbitrarias contra esos motores. Ambos están clasificados como «High».
Cómo funciona
La abstracción se rompe siempre en el mismo punto: la traducción de un filtro de metadatos portable a una consulta concreta para un almacén específico. Cuando esa traducción concatena cadenas en bruto en lugar de usar el enlace de parámetros del backend, cualquier carácter de operador que controle el usuario cambia el significado de la consulta en vez de tratarse como un dato.
En el caso de Cosmos DB, la ruta de código afectada construía una sentencia SQL de borrado a partir de identificadores de documentos. Una aplicación que reenviaba la entrada del usuario final como identificadores entregaba al atacante una palanca para salir de la cláusula WHERE prevista y alcanzar registros que no debería tocar. En el caso de Elasticsearch, OpenSearch y GemFire, caracteres manipulados dentro de la expresión de filtro escapaban de la estructura de consulta prevista y eran interpretados por el motor de destino. La vulnerabilidad no está en la base vectorial en sí — Postgres/pgvector, Elasticsearch, OpenSearch, GemFire y Cosmos DB ofrecen rutas de consulta parametrizadas seguras — sino en el código de pegamento que ensamblaba las consultas por concatenación. Describimos el mecanismo, no un payload funcional.
Esto importa especialmente en RAG porque los filtros de metadatos suelen depender del contexto de la petición: el tenant, el usuario, el alcance documental. Es exactamente la entrada no confiable y propia de cada petición de la que se alimenta la inyección clásica, y los pipelines RAG la encaminan hacia un almacén que contiene todos los documentos que la aplicación ha ingerido.
Por qué importa
Una inyección en el filtro de metadatos hace colapsar el aislamiento sobre el que se apoyan los despliegues RAG. Si un atacante puede reescribir el filtro, puede potencialmente leer documentos de otros tenants, saltarse el control de acceso o — según la operación y el almacén — borrar o alterar vectores almacenados y sus registros de origen. En una aplicación Java multi-tenant, es un fallo directo de confidencialidad e integridad en la capa que debía separar los datos de los clientes. El problema de Cosmos DB alcanza un impacto alto en confidencialidad, integridad y disponibilidad; el de Elasticsearch/OpenSearch/GemFire es alcanzable sin autenticación previa en las configuraciones afectadas.
El calendario no es casual. La prensa del ecosistema Java en torno a la conferencia UberConf 2026 (14 de julio de 2026) señaló que los avisos de seguridad de Spring se multiplicaron por más de diecisiete en abril de 2026 frente a lo habitual, en gran parte porque los escáneres de vulnerabilidades asistidos por IA empezaron a encontrar fallos en el grafo de dependencias de Spring más rápido que nunca — lo que provocó lo que Broadcom describió como el mayor lote de parches de seguridad de la historia del framework. La misma cobertura señala una inyección distinta de lenguaje de expresión en código de pipeline RAG, que llegó a la ejecución remota de código en una prueba de concepto, subrayando que la fontanería de RAG, y no solo el modelo, es ahora una superficie de ataque activa.
Defensas
- Actualice. Migre a las versiones corregidas de Spring AI — 1.0.6 / 1.1.5 para Cosmos DB, y 1.0.9 / 1.1.8 para Elasticsearch, OpenSearch y GemFire. Los mantenedores indican que no se necesita ninguna otra mitigación una vez aplicado el parche.
- Nunca construya las consultas por concatenación. Use la API de consulta parametrizada o de sentencia preparada de cada backend para que los valores influidos por el usuario se enlacen siempre como datos, nunca se interpreten como sintaxis. Es la corrección de raíz para toda la clase.
- Trate el filtro de metadatos como entrada no confiable. Cuando los filtros o los identificadores deriven del contexto de la petición, valídelos contra una lista de permitidos de campos, operadores y tipos de valor esperados antes de que lleguen al almacén. Rechace los caracteres de operador inesperados en lugar de intentar escaparlos.
- Limite las credenciales de base de datos al mínimo privilegio. La cuenta del almacén del servicio RAG debe limitarse a las colecciones y operaciones estrictamente necesarias, para que una inyección exitosa no pueda alcanzar datos ajenos ni operaciones destructivas.
- Imponga el aislamiento de tenants por debajo del filtro. No confíe en una cadena de filtro de nivel de aplicación como única frontera entre tenants; respáldela con seguridad a nivel de fila, colecciones por tenant o índices separados, para que un filtro reescrito no equivalga a una lectura entre tenants.
- Registre y monitorice las consultas. Capture las consultas generadas y alerte ante anomalías — operadores inesperados, filtros sobredimensionados, borrados con identificadores de forma sospechosa — para detectar intentos de explotación y regresiones.
Estado
| Elemento | Valor |
|---|---|
| Clase | Inyección vía filtros de metadatos / identificadores en un framework RAG |
| Framework afectado | Integraciones vectoriales de Spring AI 1.0.x y 1.1.x |
| Almacenes implicados | Azure Cosmos DB; Elasticsearch, OpenSearch, GemFire (el defecto está en el código de pegamento, no en las bases) |
| Impacto | Lectura entre tenants y, según la operación, alteración o borrado de datos |
| Versiones corregidas | 1.0.6 / 1.1.5 (Cosmos DB); 1.0.9 / 1.1.8 (Elasticsearch / OpenSearch / GemFire) |
| Divulgación | 27 de abril de 2026 y 12 de junio de 2026 (avisos del proveedor); reporte responsable |
| Referencias | CVE-2026-40978, CVE-2026-47835 |
Fechas clave: 27 de abril de 2026 — aviso de inyección SQL en el almacén vectorial Cosmos DB (CVE-2026-40978), reportado por SharlongWen. 12 de junio de 2026 — aviso de inyección de filtro en Elasticsearch/OpenSearch/GemFire (CVE-2026-47835), reportado por Nitro Cao de Alibaba Cloud. 14 de julio de 2026 — cobertura del ecosistema Java sobre la oleada de avisos de Spring de abril de 2026 y sobre la inyección de lenguaje de expresión en el pipeline RAG (referenciada como CVE-2026-22738). Los números de versión y créditos son los indicados en los avisos del proveedor.