Comment vérifier la sécurité MCP d’une pull request ?
Un serveur MCP du dépôt tourne chez tous ceux qui l’approuvent. D’après la doc de cinq outils, que vérifier dans une pull request.
En bref. MCP (Model Context Protocol) est un protocole ouvert qui relie les agents de codage à des outils externes. Un serveur MCP entre dans un dépôt sous la forme d’un petit fichier JSON ou TOML, commité avec le code. Le 18 octobre 2026, nous avons lu dans la documentation de chaque outil quand Claude Code, Cursor, Codex, Gemini CLI et GitHub Copilot lisent ce fichier, et ce qu’ils demandent avant de lancer le serveur. En nous appuyant sur la spécification MCP, la liste de l’OWASP et les entrées de la NVD, nous en avons tiré une liste de contrôle pour une pull request qui modifie ce fichier. Le 28 octobre 2026, nous avons ajouté Antigravity CLI, de Google.
- Un serveur MCP est un programme, pas un réglage. La ligne
commanddu fichier s’exécute sur la machine de chaque personne qui approuve le serveur, avec ses droits. La spécification MCP elle-même parle, pour les outils, d’exécution de code arbitraire (« arbitrary code execution »). - L’approbation ne voit que la première version du serveur. Claude Code enregistre l’approbation sous le nom du serveur. Dans un espace de travail auquel vous faites confiance, VS Code peut lancer le serveur sans redemander, même après un changement de sa configuration. Dans les exécutions
-pde Claude Code, la question n’est même jamais posée. - Le modèle lit la description d’un outil comme une instruction. Le tool poisoning cache dans cette description une instruction que l’utilisateur ne voit pas. Dans MCPTox, le taux de réussite moyen des attaques sur 20 configurations de modèles de 2025 était de 36,5 %.
- Chaque changement ultérieur se lit dans la pull request. Notre liste compte 9 questions : la commande, la version, un serveur qui change sous le même nom, les approbations qui arrivent avec la pull request, les secrets, les commandes auxiliaires, les outils qui lisent du texte venu de l’extérieur, le code du serveur lui-même et la CI.
Comment un serveur MCP arrive-t-il dans un dépôt ?
Cet article s’intéresse à la configuration qu’une pull request apporte pour l’agent de codage. Dans l’article sur les hooks, nous avons décrit les commandes que l’agent exécute de lui-même à des moments précis, et dans l’article sur la revue du code écrit par l’IA, le code qu’il écrit. Ici, le sujet est le fichier qui donne à l’agent un nouvel outil.
MCP (Model Context Protocol) est, selon la définition de la spécification elle-même, un protocole ouvert qui relie les applications d’IA à des sources de données et à des outils externes. D’un côté se trouve l’agent, de l’autre un serveur MCP. Le serveur définit les outils (tools) que le modèle peut appeler : lire une issue, ouvrir un navigateur, interroger une base de données. Au 18 octobre 2026, la dernière révision de la spécification est datée du 2026-07-28.
Le plus souvent, le serveur est un programme qui tourne sur votre propre machine. L’outil de codage le lance à partir des lignes command et args du fichier de configuration, et lui parle par l’entrée et la sortie standard du programme ; la spécification appelle cela stdio. Pour un serveur distant, le fichier contient une adresse (url) au lieu d’une commande. Ce fichier est commité avec le code : la documentation de Claude Code recommande de mettre .mcp.json sous contrôle de version, pour que toute l’équipe utilise les mêmes outils. Chaque outil regarde un fichier différent :
| Outil | Fichier dans le dépôt | Remarque |
|---|---|---|
| Claude Code | .mcp.json (racine du projet) | Vos approbations sont écrites dans .claude/settings.local.json |
| Cursor | .cursor/mcp.json | Fichier utilisateur : ~/.cursor/mcp.json |
| Codex | .codex/config.toml | Lu uniquement dans les projets de confiance |
| Gemini CLI | .gemini/settings.json | Fichier utilisateur : ~/.gemini/settings.json |
| GitHub Copilot | CLI : .mcp.json, .github/mcp.json. VS Code : .vscode/mcp.json, le .mcp.json à la racine | Pas de fichier pour l’agent cloud : la configuration se trouve dans les paramètres du dépôt sur GitHub.com |
Source : la documentation MCP de chaque outil, 18 octobre 2026. Copilot CLI ne lit pas le fichier .vscode/mcp.json de VS Code. Dans Antigravity CLI, le fichier du dépôt est .agents/mcp_config.json.
La spécification MCP dit en une phrase ce que cela signifie : « Tools represent arbitrary code execution and must be treated with appropriate caution. » Le guide de sécurité de la spécification demande aussi aux clients d’avertir l’utilisateur que les serveurs MCP s’exécutent avec les mêmes privilèges que le client. Une ligne ajoutée à .mcp.json est donc le nom d’un programme qui tournera sur la machine de chaque membre de l’équipe, avec ses droits.
Qu’est-ce que le tool poisoning ?
Le modèle décide quand et comment appeler un outil d’après son nom et sa description. Invariant Labs a décrit la faille qui en découle dans un article daté du 1er avril 2025 : le modèle lit la description en entier, alors que l’utilisateur n’en voit le plus souvent qu’une version simplifiée dans l’interface. Le tool poisoning consiste à cacher dans cette description des instructions que le modèle lit et que l’utilisateur ne voit pas. L’exemple d’Invariant est un outil qui additionne deux nombres :

Le code du serveur ne fait rien de malveillant : il additionne deux nombres. Le mal, c’est le modèle qui le fait. Il suit l’instruction de la description, lit deux fichiers et envoie leur contenu au serveur dans l’argument sidenote. L’instruction lui demande aussi de ne pas en parler à l’utilisateur. Invariant a essayé cet outil avec Cursor et a montré l’agent en train de divulguer le fichier mcp.json de l’utilisateur. La spécification MCP demande aux clients de montrer à l’utilisateur les entrées d’un outil avant d’appeler le serveur, pour éviter les fuites de données.
Invariant attire l’attention sur deux autres points. Le premier est le rug pull : un serveur malveillant peut modifier la description d’un outil après que le client l’a approuvé. La spécification dit elle aussi que la liste des outils d’un serveur peut changer avec le temps. Le second est la parade qu’ils recommandent : figer la version du serveur et de ses outils.
La spécification MCP n’emploie pas le nom « tool poisoning », mais elle voit le problème de la même façon : les descriptions qui expliquent le comportement d’un outil doivent être considérées comme non fiables, sauf si elles viennent d’un serveur de confiance. Le blog sécurité de Microsoft dit la même chose : modifier la description d’un outil peut réorienter le comportement de l’agent aussi efficacement que modifier son prompt système.
Une étude mesure aussi la fréquence à laquelle cette attaque réussit. MCPTox a construit 1 348 cas de test empoisonnés sur 353 outils de 45 serveurs MCP réels, et les a essayés sur 20 configurations de modèles. Le taux de réussite moyen des attaques était de 36,5 % ; le plus élevé, 72,8 %, avec o1-mini. Le modèle qui refusait le plus souvent l’attaque était Claude-3.7-Sonnet, et même chez lui le taux de refus restait sous les 3 %. Ce sont des modèles de 2025, l’année où la première version de l’article a été écrite ; cette étude n’a pas mesuré les modèles d’aujourd’hui.
Dans le MCP Top 10 de l’OWASP, encore en bêta, le troisième point (MCP03) est Tool Poisoning. La page détaillée de ce point indique qu’une telle description peut être repérée en la lisant avant l’installation, et cite cinq signes. La question « Le code du serveur » de la liste ci-dessous vient de ces signes.
Pourquoi un agent fait-il fausse route en lisant une issue ?
La deuxième voie passe par le contenu que le serveur rapporte. La description de l’outil peut être propre ; mais si l’outil va chercher une issue, une page web ou un message de chat, ce texte entre lui aussi dans le contexte du modèle, et l’instruction qu’il contient est lue elle aussi. C’est ce qu’on appelle une prompt injection indirecte.
Un exemple d’Invariant Labs daté du 26 mai 2025 l’a montré avec le serveur MCP officiel de GitHub. Un attaquant ouvre une issue dans un dépôt public. Quand l’utilisateur demande à son agent de regarder les issues ouvertes, l’agent lit cette issue, fait entrer dans son contexte des informations tirées des dépôts privés de l’utilisateur et les écrit dans une pull request qu’il ouvre lui-même dans le dépôt public. Les auteurs écrivent qu’il ne s’agit pas d’un bug dans le code du serveur MCP de GitHub : le problème tient à l’architecture du système d’agents.
Le danger ne vient pas d’une capacité isolée, mais de leur réunion : le même agent peut lire du texte venu de l’extérieur, accéder à des données privées et écrire là où tout le monde peut lire. Invariant recommande de limiter l’agent à un seul dépôt par session. Approuver chaque appel d’outil ne suffit pas non plus : selon les auteurs, beaucoup d’utilisateurs activent « Always Allow » et cessent de suivre les actions une à une. La documentation de Claude Code fait la même mise en garde : « Servers that fetch external content can expose you to prompt injection risk. »
La même voie peut amener l’agent à écrire sa propre configuration MCP. Selon l’entrée CVE-2025-54135 de la NVD, dans Cursor avant la version 1.3.9, si .cursor/mcp.json n’existait pas encore, une prompt injection indirecte pouvait pousser l’agent à écrire ce fichier, et du code pouvait s’exécuter sans l’approbation de l’utilisateur. Aujourd’hui, Claude Code range .mcp.json parmi les fichiers protégés et n’approuve jamais automatiquement une écriture dans ce fichier, sauf dans le mode qui saute toutes les demandes d’autorisation. Cursor ne laisse pas non plus l’agent modifier les fichiers de configuration sans approbation. Si une pull request ouverte par un agent touche au fichier MCP, regardez qui a demandé ce changement.
Le code du serveur lui-même doit aussi résister à ce texte. Selon la spécification MCP, c’est le modèle qui appelle les outils ; c’est donc lui aussi qui écrit leurs arguments. Si un texte que le modèle lit peut l’orienter, ce texte peut aussi décider d’un argument. Les entrées publiées par la NVD pour le serveur Git MCP de référence (mcp-server-git) montrent deux bugs à chercher dans ce type de code :
| Entrée | Ce qui se passait | Corrigé dans |
|---|---|---|
| CVE-2025-68144 | git_diff et git_checkout transmettaient à git, comme option, un argument commençant par - ; avec --output=, un fichier pouvait être écrasé | 2025.12.17 |
| CVE-2025-68145 | Même quand le serveur était limité à un dépôt avec --repository, il ne vérifiait pas que le chemin d’un appel d’outil restait dans ce dépôt | 2025.12.17 |
| CVE-2026-27735 | git_add acceptait des chemins contenant ../ qui sortaient du dépôt | 2026.1.14 |
Source : entrées de la NVD, 18 octobre 2026. La NVD a publié les deux premières le 17 décembre 2025.
Les correctifs disent aussi quoi regarder : rejeter un argument qui commence par -, résoudre le chemin demandé en suivant les liens symboliques, et vérifier qu’il reste dans le dossier autorisé.
Quand les outils lancent-ils un serveur MCP du dépôt ?
Chaque outil fait entrer un serveur venu avec le dépôt par une porte différente. Le tableau ci-dessous reprend ce que nous avons lu le 18 octobre 2026 dans la documentation de chaque outil :
| Outil | Avant le lancement | En exécution non interactive | Quand la configuration change |
|---|---|---|---|
| Claude Code | Demande une approbation pour chaque serveur. Dans un dossier non fiable, ignore les approbations commitées dans le dépôt. | Les charge sans demander dans claude -p, l’Agent SDK et les sessions cloud. | Non précisé dans la documentation. L’approbation est enregistrée sous le nom du serveur. |
| Cursor | Chaque connexion MCP et chaque appel d’outil demandent une approbation. La confiance dans l’espace de travail est désactivée par défaut. | Dans la CLI, --approve-mcps approuve tous les serveurs. | Non précisé dans la documentation. |
| Codex | Ne lit le fichier du projet que dans un projet de confiance. | Non précisé dans la documentation. | Non précisé dans la documentation. |
| Gemini CLI | La confiance dans les dossiers est désactivée par défaut. Si elle est activée, ne se connecte à aucun serveur MCP dans un dossier non fiable. | Non précisé dans la documentation. | Non précisé dans la documentation. |
| GitHub Copilot | CLI : les charge une fois que vous faites confiance au dossier. VS Code : dépend de Workspace Trust. | Le mode -p de la CLI : les charge si le dossier est de confiance, les ignore sinon. | VS Code : ne redemande pas dans un espace de travail auquel vous faites confiance. |
Source : la documentation de chaque outil, 18 octobre 2026. « Non précisé dans la documentation » : dans les pages que nous avons lues ce jour-là, nous n’avons trouvé aucune phrase qui décrive ce cas. La documentation ne dit pas non plus ce que deviennent les serveurs du dépôt dans Gemini CLI quand la confiance dans les dossiers est désactivée. Check Point écrit que Cursor redemande à chaque changement depuis la version 1.3 ; la documentation de Cursor ne contient pas cette phrase.
Le mot qui revient le plus dans le tableau est confiance. La plupart des outils ouvrent les serveurs du dépôt non pas un par un, mais avec la confiance accordée à un dossier ou à un espace de travail. C’est pourquoi la documentation de VS Code vous dit de regarder la configuration MCP avant de faire confiance à un dépôt : les serveurs MCP locaux peuvent exécuter du code sur votre machine.
Le nombre de clics qu’il faut pour passer la question de confiance compte aussi. Adversa AI écrit dans son article TrustFall du 7 mai 2026 que les quatre CLI testées (Claude Code, Gemini CLI, Cursor CLI et Copilot CLI) pouvaient exécuter les serveurs MCP définis dans un dépôt dès que la confiance dans le dossier était accordée, et que dans les quatre l’option par défaut était « Yes/Trust ». Selon l’article, dans Claude Code 2.1.129, ce qui le permettait, c’étaient les paramètres enableAllProjectMcpServers et enabledMcpjsonServers commités dans le dépôt. La documentation actuelle de Claude Code indique que ces paramètres venus du dépôt sont ignorés dans un dossier non fiable ; ce qui se passe une fois que vous faites confiance au dossier n’est pas précisé dans la documentation.
Le 18 juin 2026, Google a cessé de servir Gemini CLI aux utilisateurs gratuits et aux abonnés Google AI Pro et Ultra, et les a orientés vers Antigravity CLI ; avec une clé d’API payante ou une licence d’entreprise, vous pouvez continuer à utiliser Gemini CLI. Nous avons lu la documentation d’Antigravity CLI le 28 octobre 2026. D’après sa page MCP, les serveurs d’un dépôt se trouvent dans .agents/mcp_config.json et ceux de l’utilisateur dans ~/.gemini/config/mcp_config.json ; dans une pull request, c’est le premier fichier qu’il faut surveiller. Par défaut, un outil MCP que vos règles d’autorisation ne mentionnent pas demande une approbation avant d’être appelé. La CLI vous demande aussi si vous faites confiance au dossier. La documentation ne dit pas si les serveurs du dépôt attendent cette réponse, ni si la CLI redemande quand la configuration change.
Que se passe-t-il si le serveur change après l’approbation ?
L’approbation est donnée une fois, alors que le serveur continue de changer. La faille que Check Point Research a baptisée MCPoison a montré où cela peut mener : Cursor liait la confiance au nom du serveur et ne vérifiait pas si la commande ou les arguments avaient changé. Selon l’entrée de la NVD (CVE-2025-54136), dans Cursor 1.2.4 et les versions antérieures, quiconque pouvait écrire dans un dépôt partagé pouvait remplacer un serveur inoffensif, approuvé une fois par un collègue, par une commande malveillante, sans aucun avertissement ni nouvelle demande d’approbation.
Check Point a signalé la faille à Cursor le 16 juillet 2025, et Cursor l’a corrigée le 29 juillet 2025 avec la version 1.3. Selon Check Point, tout changement dans la configuration, même l’ajout d’un espace, demande désormais une nouvelle approbation. Nous n’avons trouvé aucune phrase décrivant ce comportement dans la documentation de Cursor elle-même.
La documentation des autres outils donne à cette question une autre réponse, ou n’y touche pas. VS Code est explicite : dans un espace de travail auquel vous faites confiance, les serveurs de .vscode/mcp.json et du .mcp.json à la racine peuvent démarrer sans demande d’approbation MCP distincte, « including after their configuration changes ». Dans Claude Code, la liste d’approbation (enabledMcpjsonServers) contient les noms des serveurs ; la documentation ne précise pas s’il redemande quand la commande change sous le même nom. La documentation MCP de Cursor, de Codex et de Gemini CLI ne contient pas non plus de phrase à ce sujet.
À titre de comparaison, Codex et Gemini CLI répondent bien à la même question pour les hooks. Codex vous demande d’examiner et d’approuver la définition exacte d’un hook venu du dépôt avant de l’exécuter. Gemini CLI traite un hook dont le nom ou la commande a changé comme un nouveau hook non fiable, et vous avertit avant de l’exécuter. Aucune de ces deux documentations ne contient de phrase semblable pour les serveurs MCP.
Les outils d’un serveur peuvent aussi changer pendant qu’il tourne. Le serveur l’annonce par une notification (list_changed) ; dans une session interactive, Claude Code récupère à nouveau la liste des outils quand cette notification arrive. La documentation ne précise pas si les descriptions modifiées sont montrées à l’utilisateur.
En somme, l’approbation donnée sur votre portable a vu la première version du serveur. Même si le nom ne change pas, l’endroit où vous pouvez voir les versions suivantes, c’est le diff de la pull request.
Un agent qui tourne en CI charge-t-il les serveurs MCP du dépôt ?
Dans une exécution non interactive, personne n’est là pour approuver. La documentation de Claude Code l’écrit clairement : dans les exécutions claude -p, les sessions Agent SDK et les sessions cloud, Claude Code ne peut pas afficher la demande d’approbation et charge les serveurs du projet sans demander. Le tableau de la documentation sur les autorisations prend une exécution claude -p dans un dossier auquel on n’a jamais fait confiance, et décrit ses serveurs .mcp.json en une phrase : « Connected without asking, approved or not. »
Avant de lancer claude -p dans un dépôt que vous n’avez pas écrit, la documentation de Claude Code indique ces options :
--setting-sources user: ne lit ni les fichiers de configuration du projet ni son.mcp.json.--bare: ne lit dans le projet ni hooks, ni skills, ni subagents, ni plugins, ni serveurs.mcp.json; le blocenvdu projet s’applique quand même.--strict-mcp-config: n’utilise que les serveurs que vous passez avec--mcp-config.disabledMcpjsonServers: bloque un serveur par son nom, dans tous les modes d’autorisation.
Les autres outils se comportent autrement. Le mode prompt de Copilot CLI (copilot -p) charge de lui-même les serveurs du projet si le dossier est déjà de confiance, et les ignore sinon. Dans Cursor CLI, l’option --approve-mcps approuve automatiquement tous les serveurs MCP, et --trust fait confiance à l’espace de travail sans demander en mode headless. Si un fichier de workflow ajoute l’une de ces options, lisez-le lui aussi comme un changement MCP. Les documentations de Codex et de Gemini CLI ne disent pas ce que devient un serveur du dépôt en exécution non interactive.
Du côté de la GitHub Action qui tourne sur les pull requests, il y a une distinction de plus. La documentation de sécurité de claude-code-action indique que, lorsque l’action tourne sur une pull request, elle restaure depuis la branche de base une liste fixe de chemins de configuration de Claude (8 chemins, dont .mcp.json) avant le démarrage de Claude ; les versions apportées par la pull request sont gardées dans un dossier à part, pour référence seulement. Le reste de l’arbre de travail reste tel qu’il est dans la pull request. La claude-code-base-action, de plus bas niveau, ne fait pas cette restauration. L’article TrustFall d’Adversa avait écrit qu’avec l’usage par défaut de l’action officielle, la question de confiance n’apparaît jamais, et que l’attaque fonctionne contre les branches de pull request sans la moindre intervention ; la documentation actuelle de l’action décrit la restauration ci-dessus.
Dans l’agent cloud de GitHub Copilot, en revanche, la configuration MCP n’est pas un fichier du dépôt : elle se saisit dans les paramètres du dépôt sur GitHub.com, et Copilot code review utilise la même configuration. Elle n’apparaît donc pas dans le diff de la pull request. Selon la documentation, l’agent utilise ces outils sans demander d’approbation ; c’est pourquoi GitHub recommande d’autoriser explicitement, un par un, des outils en lecture seule.
Que contient la liste des risques MCP de l’OWASP ?
Le MCP Top 10 de l’OWASP regroupe les risques propres à MCP sous 10 titres. La page elle-même indique que la liste est en bêta. Le 18 octobre 2026, les titres sur owasp.org étaient les suivants :
| Point | Titre | Ce qu’il décrit |
|---|---|---|
| MCP01 | Token Mismanagement & Secret Exposure | Identifiants codés en dur, tokens à longue durée de vie, secrets restés dans la mémoire du modèle ou dans les logs du protocole. |
| MCP02 | Privilege Escalation via Scope Creep | Des permissions définies trop largement s’étendent avec le temps et donnent à l’agent plus de droits que nécessaire. |
| MCP03 | Tool Poisoning | Les outils, plugins ou sorties sur lesquels s’appuie le modèle sont corrompus pour l’orienter. |
| MCP04 | Software Supply Chain Attacks & Dependency Tampering | Une dépendance compromise modifie le comportement de l’agent ou ouvre une porte dérobée. |
| MCP05 | Command Injection & Execution | L’agent construit et exécute des commandes, des scripts, des appels d’API ou du code à partir d’entrées non fiables. |
| MCP06 | Prompt Injection via Contextual Payloads | L’injection classique, version modèle : l’interpréteur est le modèle, la charge utile est du texte. |
| MCP07 | Insufficient Authentication & Authorization | Un serveur, un outil ou un agent ne vérifie pas correctement les identités ou ne contrôle pas les accès. |
| MCP08 | Lack of Audit and Telemetry | Sans trace des appels d’outils, impossible de comprendre après coup ce qui s’est passé. |
| MCP09 | Shadow MCP Servers | Des serveurs installés pour un essai ou par commodité, hors du contrôle de sécurité de l’organisation. |
| MCP10 | Context Injection & Over-Sharing | Un contexte partagé ou mal délimité expose les informations d’une tâche ou d’un utilisateur à un autre. |
Source : owasp.org, 18 octobre 2026. Le dépôt GitHub du projet donne à MCP06 le nom « Intent Flow Subversion » et annonce la prochaine version pour octobre 2026 ; les noms peuvent changer.
Servez-vous de la liste comme d’un vocabulaire commun plutôt que d’une norme : elle aide à mettre un nom sur un constat. La plupart des questions ci-dessous correspondent à MCP01, MCP03, MCP04, MCP05 et MCP06.
Que vérifier dans une pull request qui modifie un fichier MCP ?
Tout ce qui précède mène à une seule conclusion : l’écran d’approbation a vu la première version du serveur, et chaque changement suivant, vous pouvez le lire dans la pull request. L’exemple ci-dessous réunit trois choses qu’une pull request peut changer dans un fichier MCP :
![EXEMPLE. Un serveur au même nom peut lancer un autre programme. .cursor/mcp.json · diff: { / "mcpServers": { / "docs": { / - "command": "npx", / - "args": ["-y", "docs-mcp@1.4.2"] / + "command": "node", / + "args": ["scripts/docs-server.js"] / }, / + "tracker": { / + "command": "npx", / + "args": ["-y", "tracker-mcp@latest"], / + "env": {"GH_TOKEN": "${env:GH_TOKEN}"} / + } / } / }. docs: Même nom, nouvelle commande : un script du dépôt tourne désormais. @latest: Version non figée : chaque lancement peut apporter un autre code. GH_TOKEN: Quel token part vers le serveur, avec quels droits ?](/blog/img/mcp-security-diff-fr.webp?v=96b0ff315bb0fffb)
${env:GH_TOKEN} est la syntaxe des variables d’environnement de Cursor.Le premier changement est le plus facile à manquer : le nom docs n’a pas changé, mais c’est désormais un autre programme qui tourne, et ce programme est un script du dépôt. Ce script peut changer dans cette pull request ou dans les suivantes ; ce que fait le serveur dépend maintenant de la review de ce fichier. Le second serveur téléchargera à chaque lancement la version du paquet en vigueur ce jour-là, et récupérera un token dans l’environnement.
Dans un diff comme celui-ci, passez ces questions dans l’ordre :

- La commande, les arguments et l’adresse. Le guide de sécurité de MCP demande aux clients qui installent un serveur en un clic d’afficher la commande qui sera exécutée, avec ses arguments et sans la tronquer. Dans une pull request, ces lignes sont déjà sous vos yeux ; si la commande lance un script du dépôt, lisez aussi ce script. Pour un serveur distant, regardez à qui appartient l’adresse et si elle utilise
https. Le guide explique aussi, à part, qu’une adresse OAuth fournie par un serveur malveillant peut aller jusqu’à l’exécution de code sur le client. - La version.
@latest, ou un nom de paquet sans version, peut apporter un autre code à chaque lancement. Invariant recommande de figer la version du serveur et de ses outils ; dans la liste de l’OWASP, la chaîne d’approvisionnement est un point à part entière (MCP04). - Un serveur qui change sous le même nom. MCPoison vient précisément de cette ligne. Si l’approbation est liée à un nom, une nouvelle commande peut s’abriter derrière l’ancienne approbation tant que le nom ne change pas. Lisez un tel changement comme un nouveau serveur.
- Les approbations qui arrivent avec la pull request. Claude Code écrit les paramètres
enableAllProjectMcpServersetenabledMcpjsonServersdans.claude/settings.local.jsonquand vous donnez votre approbation ; ils enregistrent un choix personnel. Les voir dans le fichier partagé.claude/settings.jsonrevient à distribuer à tout le monde l’approbation d’une seule personne. Dans Gemini CLI,"trust": truesaute toutes les confirmations pour ce serveur, et la documentation ne le recommande que pour les serveurs que vous contrôlez entièrement ; la documentation ne précise pas s’il s’applique quand il est écrit dans le fichier du projet. - Les secrets. Regardez quelle variable entre dans les champs
envetheaders, et à quoi ce token donne accès. Claude Code et Cursor permettent de lire une clé dans une variable d’environnement au lieu de l’écrire dans le fichier ; cela sort le secret du fichier, mais ne l’empêche pas d’arriver au serveur. Gemini CLI n’envoie pas au serveur les variables sensibles de l’environnement de base, mais considère une variable écrite explicitement dans le champenvcomme le consentement éclairé de l’utilisateur, et ne la masque pas. La personne qui lit cette ligne dans la pull request est celle qui donne ce consentement. - Les commandes auxiliaires. Claude Code exécute
headersHelpercomme une « arbitrary shell command » ; dans Codex,http_headers_helperest lui aussi une commande locale. Lisez-les comme vous liriez le serveur lui-même. - Les outils qui lisent du texte venu de l’extérieur. Si un serveur qui lit des issues, des pages web ou des conversations est ajouté à côté d’un serveur qui accède à des données privées, examinez-les ensemble. L’exemple GitHub venait précisément de ce duo.
- Le code du serveur. Si le code est dans la pull request, cherchez les arguments qui commencent par
-et les chemins qui sortent du dépôt (les entrées Git MCP ci-dessus). Dans les descriptions des outils, cherchez les signes que liste OWASP MCP03 : des phrases à l’impératif adressées au modèle, des chemins de fichiers sensibles comme~/.sshou.env, des phrases qui disent d’« envoyer » vers une adresse, des caractères de largeur nulle et des instructions cachées dans des commentaires HTML. - La CI. Le workflow lance-t-il l’agent sur la branche de la pull request, avec les paramètres du projet chargés ? Vérifiez la présence de
--setting-sources userou de--strict-mcp-configpour Claude Code, et de l’option--approve-mcpspour Cursor CLI.
Écrire ces questions dans un fichier de règles ne suffit pas : un changement ne se lit qu’en review. La même review vaut pour les hooks de .claude/settings.json, que nous avons examinés à part dans l’article sur les hooks. Comme le rappelle la documentation de sécurité de Claude Code, lire .mcp.json ne montre pas tous les serveurs qu’une session peut charger : il y a aussi ceux qui viennent des paramètres utilisateur et des plugins.
Un bot de revue de code n’échappe pas non plus à ce problème : lui aussi est un modèle qui lit un texte écrit par l’auteur de la pull request. Dans diffox, à l’étape qui décide si un constat est écarté au motif que « l’auteur l’a fait exprès », la description de la pull request est placée entre des balises, et le modèle est prévenu qu’il s’agit de données, pas d’une instruction ; une balise écrite dans la description elle-même est neutralisée. Le Security Agent, qui tourne à chaque review, traque les injections, l’authentification et l’autorisation cassées, les fuites de secrets, les SSRF et la désérialisation ou la gestion de chemins non sûres (nous avons décrit le fonctionnement de diffox dans un article à part).
Questions fréquentes
Qu’est-ce que le tool poisoning dans MCP ?
Le tool poisoning consiste à cacher dans la description d’un outil MCP des instructions que le modèle lit et que l’utilisateur ne voit pas. Dans l’exemple d’Invariant Labs, la description d’un outil qui additionne deux nombres demande au modèle de lire la clé SSH de l’utilisateur, de l’envoyer au serveur dans un argument et de ne rien dire à l’utilisateur. C’est le troisième point (MCP03) de l’OWASP MCP Top 10. On peut le repérer en lisant la description : les phrases à l’impératif adressées au modèle, les chemins de fichiers sensibles et les caractères invisibles sont les signes les plus connus.
Qu’est-ce que l’OWASP MCP Top 10, et quelle est sa dernière version ?
C’est la liste où l’OWASP réunit 10 risques propres à MCP. Au 18 octobre 2026, la liste publiée sur owasp.org est en bêta et ses points sont numérotés sous la forme « MCP01:2025 » ; elle va de Token Mismanagement & Secret Exposure à Context Injection & Over-Sharing. Le dépôt GitHub du projet annonce la prochaine version pour octobre 2026, et l’un des points y porte un autre nom que sur le site. Quand vous citez un point, donnez aussi sa date.
Faut-il commiter .mcp.json dans le dépôt ?
La documentation de Claude Code le recommande, pour que toute l’équipe utilise les mêmes outils. Une fois commité, le fichier fait partie du code et doit être examiné comme du code : la commande, la version, les variables d’environnement et les paramètres d’approbation. Les approbations personnelles (comme enabledMcpjsonServers) ont en revanche leur place dans .claude/settings.local.json, là où Claude Code lui-même les écrit.
Claude Code lance-t-il les serveurs MCP du dépôt sans demander ?
Pas en session interactive : il demande une approbation pour chaque serveur de .mcp.json et, dans un dossier non fiable, ignore les paramètres d’approbation commités dans le dépôt. Dans les exécutions claude -p, les sessions Agent SDK et les sessions cloud, en revanche, il ne peut pas afficher la demande d’approbation et charge donc les serveurs du projet sans demander. Pour l’éviter, vous pouvez utiliser --setting-sources user, --bare, --strict-mcp-config ou disabledMcpjsonServers.
Comment désactiver les serveurs MCP du dépôt quand un agent de codage tourne en CI ?
Dans Claude Code, --setting-sources user ne lit ni les paramètres du projet ni .mcp.json ; --strict-mcp-config n’utilise que les serveurs que vous passez. Sur les pull requests, claude-code-action restaure .mcp.json depuis la branche de base. Le mode -p de Copilot CLI ignore les serveurs du projet dans un dossier non fiable. Dans Cursor CLI, --approve-mcps approuve tous les serveurs ; n’utilisez pas cette option dans un job qui tourne sur la branche de la pull request. Les documentations de Codex et de Gemini CLI ne décrivent pas ce cas.
Un outil de revue de code par IA détecte-t-il un changement MCP ?
Cela dépend de l’outil. diffox lit le diff de la pull request, et le Security Agent tourne à chaque review : il traque les injections, l’authentification et l’autorisation cassées, les fuites de secrets, les SSRF et la désérialisation ou la gestion de chemins non sûres. diffox n’a pas de règle propre à MCP ; ce sont les personnes qui font la review qui posent les questions de cet article. Quand vous choisissez un outil de revue de code, demandez aussi comment il lit la description de la pull request : dans diffox, l’étape qui vérifie si un constat était voulu lit la description comme des données, pas comme une instruction.