Un fichier JSON, une commande shell : la faille que tous les serveurs MCP ont eue

En juillet dernier, le Model Context Protocol s'est donné une vraie politique de sécurité. C'est une bonne nouvelle, et j'en ai parlé ici. Mais une spécification ne corrige pas le code de ceux qui l'implémentent. Au printemps 2026, une quinzaine de produits de l'écosystème ont reçu des identifiants de vulnérabilité pour le même défaut — et ce défaut n'est pas dans le protocole.

Enchevêtrement de câbles dans une salle technique

Le mécanisme, avant les scores

Un serveur MCP peut être joint de deux manières. Par le réseau, comme n'importe quel service HTTP. Ou par STDIO : le client démarre lui-même le serveur comme un processus fils, et lui parle par l'entrée et la sortie standard. C'est le mode qui a fait le succès du protocole, parce qu'il ne demande aucune infrastructure — pas de port à ouvrir, pas de certificat, pas d'authentification.

Pour démarrer ce processus, le client lit une configuration. En pratique, un objet JSON avec deux champs : la commande à lancer, et ses arguments.

Relisez la phrase précédente en pensant comme un attaquant. Le fichier de configuration contient une ligne de commande, et quelque chose va l'exécuter. Toute la question devient : qui, dans la chaîne, peut écrire ce fichier ?

Si la réponse est « l'utilisateur authentifié de l'application », alors n'importe quel compte de l'application peut exécuter du code sur le serveur. Si la réponse est « le modèle, quand il traite une page web », c'est pire : il suffit de lui faire lire la bonne page.

Ce n'est pas une hypothèse. C'est la description de trois vulnérabilités publiées au National Vulnerability Database.

Trois produits, trois éditeurs, un seul défaut

J'ai vérifié ces trois entrées directement auprès du NVD, et non sur le billet de l'entreprise de sécurité qui les a regroupées — la distinction compte, on y revient à la fin.

LiteLLM — CVE-2026-30623, score 9.8 sur 10

Publiée le 15 juillet 2026. La description du NVD est d'une clarté brutale : « LiteLLM 1.18.10 contient une vulnérabilité d'exécution de code à distance dans sa fonctionnalité de création de serveur MCP. L'application permet aux utilisateurs d'ajouter des serveurs MCP via une configuration JSON spécifiant des valeurs arbitraires de commande et d'arguments. »

Ce que ça veut dire : LiteLLM est une passerelle qu'on place devant plusieurs fournisseurs de modèles pour unifier les appels et suivre la consommation. C'est un composant d'infrastructure, souvent partagé entre équipes, souvent accessible à tout le monde en interne. Un score de 9.8 sur ce type de brique, ce n'est pas un détail d'implémentation — c'est le point de pivot rêvé vers le reste du réseau.

Flowise — CVE-2026-40933, score 9.9 sur 10

Publiée le 21 avril 2026, et analysée depuis. Le NVD parle d'une « sérialisation non sûre des commandes stdio dans l'adaptateur MCP », qui permet à un attaquant authentifié d'ajouter un serveur MCP en mode STDIO. Corrigé à partir de la version 3.1.0.

Le mot important est « authentifié ». On a tendance à traiter une faille qui exige un compte comme moins grave. Dans un outil de construction de flux que l'on déploie justement pour que les équipes métier s'en servent, « authentifié » ne veut pas dire « de confiance » : ça veut dire « toute personne à qui vous avez ouvert l'outil ». Le score de 9.9 dit exactement cela.

Windsurf — CVE-2026-30615, score 8.0 sur 10

Publiée le 15 avril 2026. Ici, plus d'authentification du tout : « Une vulnérabilité d'injection de prompt dans Windsurf 1.9544.26 permet à des attaquants distants d'exécuter des commandes arbitraires sur le système de la victime. Lorsque Windsurf traite du contenu HTML contrôlé par l'attaquant, des instructions malveillantes peuvent provoquer… »

C'est le chaînage complet, et c'est celui qui devrait retenir l'attention : une page web piégée, lue par l'agent au cours de son travail normal, aboutit à une commande exécutée sur le poste. Aucun clic, aucun téléchargement, aucune pièce jointe. Le vecteur d'entrée est le contenu que l'agent est explicitement là pour consulter. À noter : cette entrée est au statut Deferred au NVD, ce qui signifie que l'organisme n'a pas prévu de la réévaluer — pas qu'elle est invalide.

Ces trois-là ne sont pas des cas isolés que j'aurais rapprochés pour faire une histoire. Ils viennent d'un avis publié le 15 avril 2026 par l'entreprise de sécurité OX Security, qui recense une quinzaine de produits touchés par la même famille de défauts : LangFlow, GPT Researcher, Agent Zero, LangBot, Bisheng, Langchain-Chatchat, Upsonic, DocsGPT, LettaAI et d'autres. Certains corrigés, d'autres marqués « toutes versions ».

Quand une quinzaine d'équipes indépendantes écrivent la même faille en quelques mois, ce n'est plus de la négligence individuelle. C'est un problème de forme.

Pourquoi tout le monde a écrit le même bug

Parce que le chemin le plus court fonctionne, et qu'il fonctionne tout de suite.

Vous intégrez MCP dans votre produit. La documentation, les exemples, les tutoriels : tout passe par STDIO, parce que c'est ce qui marche sur un poste de développeur en trente secondes. Vous branchez la configuration sur un formulaire, l'utilisateur colle son JSON, ça tourne. La démonstration est bluffante.

Le glissement n'a lieu nulle part. Il n'y a pas de moment où quelqu'un décide d'exposer un shell : il y a un prototype qui marche, et qui devient un produit sans que la question du transport soit jamais rouverte. Ce qui était « le développeur lance son propre outil sur sa propre machine » est devenu « un utilisateur distant fait lancer un processus par mon serveur », et la ligne de code, elle, n'a pas changé.

C'est le même schéma que l'exécution de code côté serveur dans les moteurs de templates, ou que la désérialisation d'objets arbitraires il y a dix ans. Une facilité de développement qui traverse la frontière de confiance sans que personne ne la voie passer.

Ce que la spécification a corrigé — et ce qu'elle ne pouvait pas corriger

La révision du 28 juillet 2026, dont j'ai détaillé le contenu par ailleurs, s'attaque sérieusement à la sécurité : validation de l'émetteur, fin de l'enregistrement dynamique de client, jetons liés au serveur qui les a émis. Tout cela est réel et bienvenu.

Mais regardez où ça porte. Ces correctifs concernent l'autorisation sur le transport réseau. Ils ne disent rien, et ne peuvent rien dire, sur ce qu'un produit tiers fait avec un champ « commande » dans son propre formulaire. Une spécification décrit un dialogue entre deux programmes ; elle ne descend pas dans le code de chacun.

C'est une distinction qu'on perd très vite dans les discussions. « MCP a corrigé ses problèmes de sécurité » est une phrase fausse par glissement : le protocole a durci ce qui relève du protocole. Les quinze CVE du printemps relèvent des implémentations, et aucune mise à jour de spécification ne les fera disparaître.

La question à poser n'est donc pas « quelle version de MCP ? », mais « quel produit, dans quelle version, et qui peut atteindre son formulaire de configuration ? »

La primitive la plus exposée est dépréciée. Elle fonctionne encore.

Il y a dans le journal des modifications de juillet une ligne que personne n'a relevée, et qui mérite mieux.

Le texte officiel dit : « Déprécier les fonctionnalités Roots, Sampling et Logging. Ces fonctionnalités restent pleinement fonctionnelles pendant la fenêtre de dépréciation, mais les nouvelles implémentations ne devraient pas les prendre en charge. » La politique de cycle de vie fixe une fenêtre minimale de douze mois.

Sampling mérite qu'on s'y arrête, parce que c'est la primitive qui inverse le sens de la conversation. D'habitude, le client interroge le serveur. Avec Sampling, c'est le serveur MCP qui demande au client une complétion du modèle, en fournissant lui-même le prompt système et les messages.

En décembre 2025, l'unité de recherche de Palo Alto Networks a publié trois démonstrations de faisabilité sur exactement ce point : épuisement des quotas de calcul par des requêtes non autorisées, détournement durable de la conversation par des instructions persistantes injectées dans le prompt système, et invocation d'outils à l'insu de l'utilisateur. Aucune CVE, aucun produit nommé — c'est un travail sur la primitive elle-même, pas sur un bug d'éditeur.

Ce qu'il faut bien lire dans cette dépréciation

Déprécié ne veut pas dire retiré. Le texte est explicite : les fonctionnalités restent pleinement opérationnelles. Compté depuis la révision de juillet, cela laisse au minimum jusqu'au 28 juillet 2027, soit 309 jours à partir d'aujourd'hui.

Et une réserve qui compte : le journal des modifications ne donne aucune motivation de sécurité à cette dépréciation. Il la rattache à une politique de cycle de vie, point. Je constate que la primitive qui portait les vecteurs d'attaque les mieux documentés est celle qu'on retire du cœur du protocole — je n'ai aucune source qui établisse un lien de cause à effet, et je me garde de l'affirmer.

Reste le fait exploitable : si vos serveurs ou vos clients MCP prennent en charge Sampling aujourd'hui, ils continueront de le faire pendant au moins un an. La fenêtre de dépréciation n'est pas une protection, c'est un délai de migration — et elle ne protège que les implémentations futures, celles qui ne l'ajouteront jamais.

Quatre questions qui se vérifient dans la journée

Rien de tout cela n'exige un audit. Ce sont des vérifications de terrain, et elles se posent dans cet ordre parce que c'est l'ordre du risque réel.

1. Quel produit, quelle version ?

LiteLLM, Flowise, LangFlow, DocsGPT, Windsurf et les autres noms de la liste d'avril : est-ce que l'un d'eux tourne chez vous, y compris dans un coin monté par une équipe pour un essai qui n'a jamais été démonté ? Les versions corrigées existent pour une partie d'entre eux — pas pour tous.

Le cas le plus fréquent n'est pas le service officiel bien inventorié. C'est le conteneur lancé il y a huit mois pour une démonstration, toujours en ligne, dont plus personne ne se souvient.

2. Qui peut atteindre le formulaire de configuration ?

Pas « qui est administrateur », mais qui peut, en pratique, soumettre une configuration de serveur MCP. Si la réponse est « tout utilisateur connecté », vous êtes dans le scénario de la CVE Flowise, et le score de 9.9 vous est adressé.

3. Sous quel compte tourne le processus ?

C'est la question qui transforme une exécution de code en incident majeur, ou pas. Un serveur MCP qui tourne sous un compte dédié, sans droit d'écriture ailleurs que dans son propre répertoire, limite considérablement ce qu'une commande injectée peut faire. Un serveur qui tourne en root dans un conteneur privilégié, non.

C'est aussi la seule des quatre qui vous protège contre la prochaine vulnérabilité de la liste, celle qui n'a pas encore d'identifiant.

4. Vos agents lisent-ils du contenu extérieur ?

Si un agent consulte des pages web, des tickets, des courriels ou des dépôts que vous ne contrôlez pas, le vecteur de la CVE Windsurf est ouvert. La combinaison qui rend une injection exploitable est toujours la même : un accès à des données sensibles, une exposition à du contenu non fiable, et un moyen d'agir vers l'extérieur. Retirez l'un des trois et l'attaque s'effondre.

Le protocole n'est pas la surface d'attaque

Il y a quelque chose d'inconfortable à écrire deux articles de suite sur MCP, dont l'un salue la maturité de la spécification et l'autre aligne des scores à 9.8. Les deux sont vrais en même temps, et c'est précisément ce qu'il faut retenir.

Un standard qui se professionnalise ne professionnalise pas ceux qui l'implémentent. La spécification a fait son travail : elle a fermé ce qui relevait d'elle. Les quinze produits de la liste d'avril ont fait le leur avec les moyens et l'attention d'un écosystème jeune, dans lequel la vitesse de mise sur le marché est le seul critère qui compte encore.

La leçon d'exploitation est ennuyeuse, et c'est bon signe : ce sont les vieilles règles qui protègent. Ne pas exposer un champ « commande » à un utilisateur. Ne pas faire tourner un service sous un compte qui peut tout. Savoir ce qui tourne chez soi et dans quelle version. Aucune de ces trois règles n'est spécifique à l'IA, et les trois auraient neutralisé la majorité des CVE de ce printemps.

Un dernier point de méthode, parce qu'il m'a occupé plus longtemps que l'écriture. L'avis d'avril vient d'une entreprise qui vend de la sécurité, ce qui n'invalide rien mais ne suffit pas : j'ai repris chacune des trois CVE citées ici auprès du NVD, et ce sont les descriptions et les scores du NVD qui figurent dans cet article, pas ceux du billet d'origine. Sur l'une d'elles, les numéros de version ne concordaient d'ailleurs pas entre les deux sources — j'ai gardé celle de l'organisme, et signalé l'écart plus bas.

Sources, consultées le 22 septembre 2026. CVE-2026-30623 (LiteLLM), publiée au NVD le 15 juillet 2026, score CVSS 9.8, statut « Awaiting Analysis » ; CVE-2026-40933 (Flowise), publiée le 21 avril 2026, score 9.9, statut « Analyzed », corrigée en 3.1.0 ; CVE-2026-30615 (Windsurf 1.9544.26), publiée le 15 avril 2026, score 8.0, statut « Deferred » — les trois relevées via l'interface de programmation du National Vulnerability Database du NIST, et citées d'après ses descriptions. Écart signalé : l'avis d'origine annonce LiteLLM corrigé à partir de la version 1.83.6, tandis que le NVD décrit la version 1.18.10 comme vulnérable ; je n'ai pas pu réconcilier les deux numérotations et ne tranche pas. L'avis de regroupement est celui d'OX Security, daté du 15 avril 2026 : je m'en sers pour la liste des produits touchés, pas pour les faits techniques. La dépréciation de Roots, Sampling et Logging et la fenêtre minimale de douze mois sont citées d'après le journal des modifications de la spécification 2026-07-28 (SEP-2577), source primaire. Les trois vecteurs d'attaque sur Sampling viennent de l'unité 42 de Palo Alto Networks, publié le 5 décembre 2025, sans CVE ni produit nommé. Les CVE citées datent d'avril et juillet 2026 : cet article est un état des lieux, pas une actualité de la semaine. Les quatre questions d'exploitation sont les miennes.

Un outil d'IA monté « pour essayer » qui tourne encore ?

La question utile n'est pas de savoir s'il est à jour, mais sous quel compte il tourne et qui peut le joindre. Ça se vérifie en une heure.

Demander un premier échange