ChromaToast : une RCE pré-auth dans la base vectorielle ChromaDB
La divulgation de HiddenLayer du 18 mai 2026 (CVE-2026-45829, CVSS 10.0) montre que le serveur Python de ChromaDB charge le modèle HuggingFace de l'attaquant et exécute son code avant même de vérifier l'authentification.
De quoi s’agit-il ?
Le 18 mai 2026, le chercheur de HiddenLayer Esteban Tonglet a publié ChromaToast: Served Pre-Auth, décrivant la CVE-2026-45829 — une exécution de code à distance avant authentification dans ChromaDB, l’une des bases de données vectorielles open source les plus déployées (environ 13 millions de téléchargements pip par mois, 27 500 étoiles GitHub, et des usages en production documentés chez Mintlify, Weights & Biases, Factory AI, Capital One et UnitedHealthcare). La faille porte un score CVSS 4.0 de 10.0, le maximum, et relève de CWE-94 (injection de code). Elle a été introduite en version 1.0.0 et, au moment de la divulgation, restait non corrigée jusqu’à la 1.5.8.
En résumé : tout attaquant non authentifié capable d’atteindre le serveur Python en HTTP peut exécuter du code arbitraire dans le processus de la base. ChromaDB se trouve au cœur des pipelines de génération augmentée par récupération (RAG), si bien qu’une compromission dépasse largement un seul serveur.
Comment ça marche
ChromaDB laisse le client choisir le modèle d’embedding d’une collection, en transmettant le nom du modèle et ses paramètres dans la requête de création de collection. Le serveur Python FastAPI récupère et charge ce modèle directement depuis HuggingFace. Parmi les paramètres figurant dans la requête se trouve trust_remote_code, un drapeau HuggingFace standard qui, lorsqu’il vaut true, indique à la bibliothèque de télécharger et d’exécuter les fichiers de module Python livrés à l’intérieur du dépôt du modèle. ChromaDB se contente de vérifier que les kwargs sont des types primitifs — un booléen passe —, si bien que trust_remote_code: true se propage intact jusqu’à AutoModel.from_pretrained(). Quiconque contrôle le dépôt référencé contrôle ce qui s’exécute sur l’hôte.
La seconde moitié est un défaut de séquence. L’endpoint vulnérable (POST /api/v2/tenants/{tenant}/databases/{db}/collections) est étiqueté comme authentifié, mais le serveur instancie la fonction d’embedding — téléchargeant et exécutant le modèle — avant de lancer la vérification d’authentification. Lorsque le contrôle des identifiants se déclenche enfin et que la requête est rejetée par un 500, le code de l’attaquant s’est déjà exécuté. L’endpoint V1 équivalent ne peut pas être désactivé, donc bloquer un chemin ne ferme pas la brèche. HiddenLayer résume la cause racine par deux défaillances qui se cumulent : le serveur fait confiance à un identifiant de modèle fourni par le client sans restriction, et agit sur cette confiance avant d’authentifier l’appelant — un cas d’école de « confused deputy » où la frontière de confiance a été placée au mauvais endroit.
Pourquoi c’est important
Un déclenchement réussi donne à l’attaquant les privilèges du processus ChromaDB : variables d’environnement, clés d’API, secrets montés et l’intégralité du magasin d’embeddings sur disque. L’exposition est large. Le balayage Shodan de HiddenLayer révèle que 73 % des instances ChromaDB accessibles depuis Internet exécutent la plage de versions vulnérable, et des recherches antérieures d’UpGuard recensaient plus de 1 170 déploiements publiquement accessibles — beaucoup contenant de vraies données de production — parce que ChromaDB est livré avec l’authentification désactivée par défaut.
C’est l’angle de la couche de données qui rend la chose pire qu’une simple prise de contrôle d’hôte. Une base vectorielle concentre des embeddings propriétaires et des bases de connaissances RAG. Un attaquant disposant d’un accès peut empoisonner les embeddings pour que les applications LLM en aval récupèrent un contenu contrôlé par l’attaquant comme s’il faisait autorité, et les travaux sur l’inversion d’embeddings montrent que les vecteurs stockés peuvent révéler une part substantielle de leur texte source — transformant une compromission d’infrastructure en un incident discret d’exfiltration de documents et d’atteinte à l’intégrité de l’IA.
Défenses
Comme aucun correctif n’existait pour le serveur Python lors de la divulgation, l’atténuation est surtout architecturale. Privilégiez le déploiement basé sur Rust (chroma run et les images Docker), qui ne porte pas cette faille. Si le serveur Python FastAPI doit rester en place, limitez son accessibilité réseau aux seuls hôtes applicatifs connus et de confiance, et terminez tout accès externe au niveau d’un reverse proxy qui authentifie avant que la requête n’atteigne ChromaDB. Activez l’authentification intégrée de ChromaDB et imposez TLS, appliquez le moindre privilège pour que les comptes d’ingestion ne puissent pas tout lire, et envoyez les journaux d’API vers un SIEM afin de détecter les lectures anormales ou les modifications de collections. Plus largement, traitez les bases vectorielles comme de l’infrastructure de données de production — la même isolation, la même revue d’accès et la même gestion des vulnérabilités que pour vos bases relationnelles — et analysez les artefacts de modèle avant qu’ils n’atteignent un runtime, car charger un modèle depuis un registre non fiable équivaut à exécuter du code non fiable.
État
La CVE-2026-45829 affecte ChromaDB 1.0.0 à 1.5.8 (serveur Python FastAPI uniquement ; le serveur Rust n’est pas concerné). HiddenLayer indique avoir contacté Chroma pour la première fois le 17 février 2026, avec des relances les 24 février, 5 mars et 16 avril avant de publier le 18 mai 2026 — une fenêtre d’environ 90 jours — sans avoir reçu de réponse. Vérifiez si une version postérieure à la 1.5.8 inclut le correctif en consultant le changelog de ChromaDB et l’avis GitHub avant de vous reposer sur une simple mise à jour, et appliquez de toute façon les mesures réseau et d’authentification.