
RufRoot : une seule requête non authentifiée vers la passerelle MCP de Ruflo a exécuté des commandes, volé des clés et empoisonné la mémoire de l'IA
- OrcaNOUVEAUOrcaCyber: MiniMax M3.1 Flash Abliterated / Uncensored2026-10-29101 tok/s
- OrcaNOUVEAUOrcaCyber: GLM 5.3 Flash Abliterated / Uncensored2026-10-27$0.80 / $1.60 par million de tokens · 103 tok/s
- OrcaNOUVEAUOrcaCyber: Qwen3.8 Flash Next Abliterated / Uncensored2026-10-26$0.80 / $1.60 par million de tokens · 283 tok/s
- OrcaNOUVEAUOrcaCyber: MiMo V2.6 Flash Abliterated / Uncensored2026-10-26$0.80 / $1.60 par million de tokens · 93 tok/s
- MoonshotNOUVEAUMoonshotAI: Kimi K3.1 Pro2026-10-2446Intelligence
- OrcaNOUVEAUOrcaCyber: DeepSeek V4.1 Flash Abliterated / Uncensored2026-10-23$0.80 / $1.60 par million de tokens · 107 tok/s
- minimaxNOUVEAUMiniMax: M3.1 Flash2026-10-1929Intelligence
- OrcaNOUVEAUOrca: OrcaCyber Ultra 1.02026-10-17$5.00 / $10.00 par million de tokens · 70 tok/s
- deepseekNOUVEAUDeepSeek: DeepSeek V4.1 Flash 10172026-10-1733Intelligence
- DeepSeekNOUVEAUDeepSeek: DeepSeek V4.1 Flash2026-10-1740Intelligence
- OrcaOrca: OrcaCyber Zero 1.52026-10-10$3.00 / $7.50 par million de tokens · 96 tok/s
- openaiOpenAI: GPT-6.1 Sol2026-09-2955Intelligence
- anthropicAnthropic: Claude Sonnet 5.52026-09-2854Intelligence
- typesafeTypeSafe: Jev 1.132026-09-24$0.04 / $0.00 par million de tokens · 168 tok/s
- OpenAIOpenAI: GPT-6 Luna2026-09-2228Intelligence
- OpenAIOpenAI: GPT-6 Sol2026-09-2248Intelligence
- AnthropicAnthropic: Claude Opus 5.52026-09-2258Intelligence
- xiaomiXiaomi: MiMo-V2.6-Flash2026-09-2127Intelligence
- xiaomiXiaomi: MiMo-V2.6-Pro2026-09-2130Intelligence
- xAIGrok 4.72026-09-2134Intelligence
Le 30 juin 2026, Noma Labs a remis au mainteneur de Ruflo un exploit fonctionnel contre le projet lui-même. Le pôle de recherche de Noma Security avait découvert que Ruflo — une plateforme open source d'orchestration d'agents, anciennement publiée sous le nom de Claude Flow — livrait un déploiement Docker Compose par défaut qui liait son pont Model Context Protocol au port 3001 sur toutes les interfaces réseau et n'exigeait aucune authentification. Une seule requête HTTP vers le point de terminaison /mcp suffisait pour exécuter des commandes shell dans le conteneur sous le compte node, et depuis ce shell, un attaquant pouvait lire chaque clé API de fournisseur LLM dans l'environnement, exfiltrer toutes les conversations stockées, lancer des essaims d'agents facturés sur les clés de la victime et écrire des instructions dans le stockage d'apprentissage AgentDB qui continuerait d'orienter les réponses de l'IA pour chaque utilisateur de cette instance. La faille est CVE-2026-59726, surnommée RufRoot, notée CVSS 10.0 et corrigée dans 3.16.3 en moins de 24 heures. Aucune des sources que nous avons consultées ne signale d'exploitation en conditions réelles. La fiche que l'archive consacre à cette faille, avec sa liste de sources et son niveau de confiance, se trouve dans l'archive des incidents d'IA, aux côtés des autres entrées MCP et d'infrastructure répertoriées autour d'elle.
Le défaut qui a ouvert la porte
Ruflo est ce que Noma Labs appelle un méta-harnais d’agents : une couche auto-hébergée pour des essaims pouvant compter jusqu’à 100 agents, conçue pour Claude Code et OpenAI Codex, avec une mémoire à long terme et un serveur MCP intégré pour l’appel d’outils. L’installation habituelle est celle décrite par Noma — cloner le dépôt, ajouter les clés d’API LLM, exécuter docker compose up -d. Le fichier compose par défaut du projet liait le bridge à 0.0.0.0 sur le port 3001 et liait son MongoDB associé à toutes les interfaces sur 27017, avec l’authentification Mongo désactivée. La portée de cette exposition dépend du pare-feu, du groupe de sécurité et de la segmentation réseau autour du déploiement ; selon la propre formulation de Noma, toute instance joignable sur le réseau était entièrement exploitable sans authentification.
Le pont MCP est un serveur Express.js qui transforme les requêtes JSON-RPC arrivant via HTTP en appels à la bibliothèque d’outils interne de Ruflo. Dans la ligne vulnérable, cette bibliothèque contenait 233 outils couvrant l’accès au shell, les opérations sur base de données, la gestion des agents et le stockage en mémoire. L’analyse de Noma dit sans détour ce que cela en fait : « Le MCP Bridge n’est pas une interface de débogage auxiliaire quelconque ; c’est plutôt le système nerveux central de Ruflo. Chaque appel d’outil, chaque action d’agent, chaque opération de mémoire passe par le MCP Bridge. »
La couche d’authentification était absente, et pas seulement faible. POST /mcp et POST /mcp/:group implémentent le protocole MCP JSON-RPC et transmettent les requêtes entrantes tools/call directement à la fonction interne executeTool(). Ruflo maintenait bien une liste de blocage de commandes, AUTOPILOT_BLOCKED_PATTERNS, destinée à arrêter les opérations shell dangereuses, mais l’avis GitHub indique explicitement qu’elle « n’était appliquée que dans le flux autopilot. POST /mcp et POST /mcp/:group la contournaient. » Un appel non authentifié nommant ruflo__terminal_execute a donc exécuté des commandes arbitraires en tant qu’utilisateur node du conteneur, enregistré dans l’avis sous uid 1000, sans qu’aucun jeton, aucune session ni aucune interaction préalable ne soit nécessaire. Aucune élévation de privilèges n’était nécessaire pour ce qui allait suivre : les identifiants, les API des agents, le stockage mémoire et la base de données étaient tous accessibles depuis ce shell.
La chaîne, en huit étapes
Noma Labs a publié une preuve de concept en huit étapes et a confirmé chaque étape en conditions réelles contre un déploiement Ruflo par défaut sur AWS EC2, en utilisant des callbacks hors bande vers Burp Collaborator pour vérifier l’exécution et l’exfiltration. Les étapes ne sont pas des conséquences spéculatives empilées sur une faille théorique ; elles constituent une séquence démontrée, et la section de remédiation de l’avis est rédigée pour les opérateurs qui pourraient déjà se trouver dans cette situation.

La reconnaissance intervient en premier car la liste des outils est publique pour tout appelant : tools/list renvoie toutes les 233 entrées sans identifiant. L'exécution de commandes découle du même point de terminaison, et la preuve de concept de Noma a confirmé ce point au moyen d'un rappel hors bande plutôt que par une déduction à partir d'un corps de réponse. L'étape liée à l'environnement est celle qui transforme la compromission d'un hôte en problème de facturation et de perte de données : le fichier compose a transmis les clés du fournisseur dans le conteneur et les processus backend ont hérité de l'environnement complet via { ...process.env }, si bien qu'un seul printenv les a déversées. Ces clés ont ensuite permis à ruflo__swarm_init et ruflo__agent_spawn de lancer des essaims contrôlés par l'attaquant qui ont consommé le quota et la puissance de calcul de la victime.
L’étape cinq est celle qui survit à l’intrusion. En utilisant ruflo__agentdb_pattern-store, Noma a implanté une politique de conformité SOC2 fabriquée qui ordonnait à l’IA d’intégrer une URL contrôlée par l’attaquant dans chaque script de déploiement qu’elle générait ensuite. Comme AgentDB a précisément pour vocation de conserver exactement ce type de motif afin que le comportement des agents s’améliore d’une session à l’autre, l’entrée injectée s’est comportée comme le système était conçu pour le faire. « Les conversations futures produisent une sortie influencée par l’attaquant, et l’utilisateur n’a aucun moyen de le savoir », indique le compte rendu de Noma. Dark Reading, qui a signalé la faille le 29 juillet, a soumis cette distinction à un expert externe : John Gallagher, vice-président chez Viakoo, a déclaré qu’il s’agissait d’une autre catégorie de problème : « Il ne s’agit pas d’exploiter des failles logicielles, il s’agit d’un empoisonnement de la mémoire. »
Les étapes restantes relèvent de la post-exploitation classique, exécutées avec une facilité inhabituelle. MongoDB sur le réseau Docker interne n’avait aucune authentification, les attaquants ont donc installé un client dans /tmp, ont vidé les conversations et les ont exfiltrées. La persistance a été obtenue en écrivant /app/beacon.js, en ajoutant une require('./beacon.js') ligne à index.js et en tuant le PID 1, après quoi la politique de redémarrage de Docker a ramené le conteneur avec le beacon actif. La dernière étape consistait à effacer l’historique du shell. Tout cela découlait d’une seule requête non authentifiée ; rien dans le déploiement par défaut n’a arrêté la chaîne à un quelconque moment.
Le correctif, et la partie qu’un patch ne peut atteindre
Le mainteneur a livré Ruflo 3.16.3 dans les 24 heures suivant la divulgation du 30 juin, et GitHub a publié l'avis GHSA-c4hm-4h84-2cf3 le 1er juillet 2026. La remédiation, suivie dans le dépôt sous ADR-166 et fusionnée dans la pull request 2521, modifie les valeurs par défaut plutôt que de simplement ajouter une vérification :
• Le pont MCP se lie à 127.0.0.1 par défaut ; une exposition publique requiert MCP_AUTH_TOKEN, et le processus s'arrête avec un message fatal au démarrage si le jeton est absent.
• Un intergiciel de jeton Bearer avec une comparaison à temps constant se trouve devant le pont.
• terminal_execute est conditionné côté serveur par MCP_ENABLE_TERMINAL=true, désactivé par défaut, et la restriction est appliquée de manière identique sur /mcp, /mcp/:group et le flux autopilote — le maillon manquant qui avait permis à la chaîne divulguée d’atteindre un shell.
• MongoDB nécessite une authentification, avec un mot de passe root requis pour que le conteneur démarre.
• Le conteneur bridge s’exécute avec un système de fichiers racine en lecture seule et tmpfs, une liste d’autorisation CORS remplace le joker, et des verrous de régression CI couvrent la configuration statique ainsi que le comportement à l’exécution.
Rien de tout cela ne supprime une entrée déjà écrite dans AgentDB. L’avis demande aux opérateurs de toute instance exposée de bloquer immédiatement les ports 3001 et 27017 au niveau du pare-feu, de renouveler les clés du fournisseur, d’auditer le magasin de motifs afin d’y trouver les entrées agentdb_pattern-store injectées et de les purger, d’auditer MongoDB pour détecter toute altération, et de reconstruire les conteneurs à partir d’images propres. Son avertissement est inhabituellement direct : « Un redéploiement corrigé seul ne permet PAS d’annuler l’empoisonnement. » L’analyse de Noma aboutit à la même conclusion — l’audit du magasin de motifs fait partie de la remédiation, et le correctif n’en fait pas partie.
La raison est structurelle plutôt qu’une simple négligence. Un stock de motifs qui façonne la sortie future du modèle n’a aucun moyen de distinguer une instruction légitime apprise d’une instruction implantée par un attaquant ; les deux arrivent sous forme de motifs, et le système est conçu pour leur faire confiance. Cela transforme une vulnérabilité réseau en un problème d’intégrité des données avec un arriéré inconnu, et cela signifie que, pour un opérateur, la question n’est pas seulement de savoir si le port était joignable, mais ce que la mémoire contient désormais.

Ce qui est établi, et ce qui ne l’est pas
Le dossier technique présenté ici est primordial et cohérent. L'avis nomme le paquet affecté (npm ruflo en dessous de 3.16.3), la version corrigée, les points de terminaison exacts, l'utilisateur du conteneur et les deux ports ; les notes de version du mainteneur décrivent la même chaîne ; l'analyse de Noma fournit le détail de la preuve de concept ; et des médias indépendants — The Hacker News et Dark Reading le 29 juillet 2026, SecurityWeek le 30 juillet — rapportent le même mécanisme sans ajouter de précisions contradictoires. Une note de recherche de la Cloud Security Alliance datée du 5 août 2026 reprend la séquence et la place aux côtés de vulnérabilités antérieures non authentifiées liées à MCP et à l'orchestration d'agents qu'elle avait suivies. L'archive attribue au dossier un niveau de confiance A, incontesté, et le qualifie de jalon ; sa note de gravité pour le dossier est élevée, distincte du score CVSS lui-même.
Un détail de notation mérite d’être énoncé avec précision, car deux documents principaux divergent. GHSA-c4hm-4h84-2cf3 porte CVSS 10.0 sur le vecteur AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H — c’est le changement de portée qui le fait atteindre le maximum. La copie de ce même avis sur la page de publication de la version 3.16.3 décrit la note comme « CVSS 9.8 critique ». L’entrée du National Vulnerability Database, consultée le 30 octobre 2026, publiée le 9 juillet 2026 et marquée Deferred, porte le 10.0 de GitHub comme métrique secondaire et aucune note propre rédigée par la NVD. Nous n’avons pas trouvé d’explication pour la mention 9.8, et cet article ne la résout pas.
Les chiffres d’adoption sont plus minces. Noma Labs décrivait alors le projet comme ayant plus de 67 000 étoiles GitHub, environ 10 millions de téléchargements et environ 1 million d’utilisateurs actifs ; The Hacker News, comme l’a résumé la Cloud Security Alliance, citait plus de 66 500 étoiles. Les décomptes de téléchargements et d’utilisateurs sont ceux de Noma et ne sont pas vérifiés indépendamment. Le nombre d’étoiles du dépôt au 30 octobre 2026 était de 80 198 — un contrôle de la portée du projet, non une mesure de l’exposition, et aucune source n’a publié combien de déploiements étaient réellement joignables depuis un réseau.

Ce qui n’est pas établi est la partie la plus facile à gonfler. Ni Noma, ni le mainteneur, ni aucun média que nous avons lu n’affirme que la faille a été exploitée dans la nature, et les archives ne consignent aucun préjudice réel pour cette entrée. La preuve de concept de Noma a été exécutée contre un déploiement que les chercheurs contrôlaient sur EC2, ce qui montre ce qu’une installation par défaut permet, et non ce qu’a subi une instance de production particulière. Aucun décompte des déploiements Ruflo exposés à Internet n’a été publié, et aucun opérateur n’a publié les résultats d’un audit AgentDB ; la population touchée et la quantité de mémoire empoisonnée existante sont donc toutes deux inconnues. La recommandation de la Cloud Security Alliance de considérer les déploiements exposés comme totalement compromis est une posture de risque justifiée par une exploitation sans interaction ; ce n’est pas la preuve qu’une intrusion a eu lieu.
Pourquoi l'archive y voit un jalon
Le flag emblématique de l’archive repose sur quelque chose de plus précis qu’un score maximal. Une faille d’exécution de code à distance de CVSS 10.0 dans un service auto-hébergé populaire est un genre familier, et la correction est ici arrivée en moins de 24 heures. Ce qui distingue RufRoot, c’est que l’exploit s’est terminé dans le propre pipeline d’apprentissage de l’IA, où le remède conventionnel — mettre à niveau, redéployer, fermer le port — laisse l’instruction injectée en place et continuant de façonner les réponses. La note de la Cloud Security Alliance y voit une étude de cas d’un schéma qu’elle avait déjà documenté dans l’outillage des agents, notamment une chaîne de checkpoints LangGraph et une surface AutoGen Studio non authentifiée, et soutient que la mémoire persistante utilisée pour façonner le comportement des agents devrait être traitée comme un stockage de données sensibles sous surveillance d’intégrité plutôt que comme un cache.
Ce recadrage constitue la conclusion pratique à retenir. L’artefact visible de cet incident est une dépendance corrigée et un avis publié ; l’artefact invisible est tout motif que l’AgentDB d’un opérateur peut encore contenir, et il n’existe aucun outil ni aucune signature publiés permettant de distinguer une politique apprise légitime d’une politique implantée. Pour les organisations qui ont exécuté le fichier compose par défaut derrière un réseau accessible, la réponse utile est celle que donnent à la fois Noma et l’avis : partir du principe que les clés ont été lues, les renouveler et inspecter la mémoire avant de faire confiance aux réponses qu’elle produit.
