ChromaToast: una RCE pre-autenticación en la base vectorial ChromaDB
La divulgación de HiddenLayer del 18 de mayo de 2026 (CVE-2026-45829, CVSS 10.0) muestra que el servidor Python de ChromaDB carga el modelo HuggingFace del atacante y ejecuta su código antes de comprobar la autenticación.
¿Qué es esto?
El 18 de mayo de 2026, el investigador de HiddenLayer Esteban Tonglet publicó ChromaToast: Served Pre-Auth, que describe la CVE-2026-45829: una ejecución remota de código previa a la autenticación en ChromaDB, una de las bases de datos vectoriales de código abierto más desplegadas (alrededor de 13 millones de descargas pip al mes, 27 500 estrellas en GitHub y usos en producción documentados en Mintlify, Weights & Biases, Factory AI, Capital One y UnitedHealthcare). El fallo tiene una puntuación base CVSS 4.0 de 10.0, la máxima, y se clasifica como CWE-94 (inyección de código). Se introdujo en la versión 1.0.0 y, en el momento de la divulgación, seguía sin parchear hasta la 1.5.8.
En resumen: cualquier atacante no autenticado que pueda alcanzar el servidor Python por HTTP puede ejecutar código arbitrario dentro del proceso de la base de datos. ChromaDB se sitúa en el centro de las canalizaciones de generación aumentada por recuperación (RAG), por lo que una vulneración va mucho más allá de un único servidor.
Cómo funciona
ChromaDB permite que el cliente elija qué modelo de embedding usa una colección, transmitiendo el nombre del modelo y sus parámetros en la petición de creación de colección. El servidor Python FastAPI obtiene y carga ese modelo directamente desde HuggingFace. Uno de los parámetros que el cliente puede fijar es trust_remote_code, una bandera estándar de HuggingFace que, cuando vale true, indica a la biblioteca que descargue y ejecute los archivos de módulo Python incluidos dentro del repositorio del modelo. ChromaDB solo valida que los kwargs sean de tipos primitivos —un booleano pasa—, de modo que trust_remote_code: true fluye intacto hasta AutoModel.from_pretrained(). Quien controle el repositorio referenciado controla lo que se ejecuta en el host.
La otra mitad es un defecto de orden. El endpoint vulnerable (POST /api/v2/tenants/{tenant}/databases/{db}/collections) está etiquetado como autenticado, pero el servidor instancia la función de embedding —descargando y ejecutando el modelo— antes de ejecutar la comprobación de autenticación. Para cuando la verificación de credenciales se activa y la petición se rechaza con un 500, el código del atacante ya se ha ejecutado. El endpoint V1 equivalente no puede deshabilitarse, así que bloquear una ruta no cierra el agujero. HiddenLayer resume la causa raíz como dos fallos que se potencian: el servidor confía en un identificador de modelo proporcionado por el cliente sin restricción, y actúa sobre esa confianza antes de autenticar a quien llama, un caso de manual de «confused deputy» en el que la frontera de confianza se colocó en el punto equivocado.
Por qué importa
Un disparo exitoso otorga al atacante los privilegios del proceso de ChromaDB: variables de entorno, claves de API, secretos montados y todo el almacén de embeddings en disco. La exposición es amplia. El barrido con Shodan de HiddenLayer revela que el 73 % de las instancias de ChromaDB accesibles desde Internet ejecutan el rango de versiones vulnerable, y una investigación previa de UpGuard catalogó más de 1170 despliegues de acceso público —muchos con datos reales de producción— porque ChromaDB se entrega con la autenticación desactivada por defecto.
El ángulo de la capa de datos es lo que lo hace peor que una simple toma de control del host. Una base vectorial concentra embeddings propietarios y bases de conocimiento RAG. Un atacante con acceso puede envenenar los embeddings para que las aplicaciones LLM aguas abajo recuperen contenido controlado por el atacante como si fuera autoritativo, y la investigación sobre inversión de embeddings muestra que los vectores almacenados pueden filtrar una parte sustancial de su texto de origen, convirtiendo una vulneración de infraestructura en un incidente silencioso de exfiltración de documentos y de pérdida de integridad de la IA.
Defensas
Como no existía un parche para el servidor Python en el momento de la divulgación, la mitigación es sobre todo arquitectónica. Prefiera la vía de despliegue basada en Rust (chroma run y las imágenes de Docker), que no arrastra este fallo. Si el servidor Python FastAPI debe permanecer, restrinja su accesibilidad de red solo a los hosts de aplicación conocidos y de confianza, y termine todo acceso externo en un reverse proxy que autentique antes de que la petición llegue a ChromaDB. Active la autenticación integrada de ChromaDB e imponga TLS, aplique el mínimo privilegio para que las cuentas de ingesta no puedan leerlo todo, y envíe los registros de la API a un SIEM para detectar lecturas anómalas o modificaciones de colecciones. En términos más generales, trate las bases vectoriales como infraestructura de datos de producción —el mismo aislamiento, revisión de accesos y gestión de vulnerabilidades que ya aplica a sus bases relacionales— y analice los artefactos de modelo antes de que lleguen a cualquier runtime, porque cargar un modelo desde un registro no confiable equivale a ejecutar código no confiable.
Estado
La CVE-2026-45829 afecta a ChromaDB de la 1.0.0 a la 1.5.8 (solo el servidor Python FastAPI; el servidor Rust no está afectado). HiddenLayer indica que contactó por primera vez con Chroma el 17 de febrero de 2026, con seguimientos el 24 de febrero, el 5 de marzo y el 16 de abril antes de publicar el 18 de mayo de 2026 —una ventana de aproximadamente 90 días— sin recibir respuesta. Verifique si alguna versión posterior a la 1.5.8 incluye la corrección consultando el changelog de ChromaDB y el aviso de GitHub antes de confiar solo en una actualización, y aplique de todos modos las medidas de red y de autenticación.