Abus de GitHub MCP : accès à des dépôts privés via MCP
(invariantlabs.ai)- Une vulnérabilité critique a été découverte dans l’intégration GitHub MCP, permettant à un attaquant de manipuler l’agent d’un utilisateur via une GitHub Issue malveillante et d’exfiltrer des données de dépôts privés
- Cette vulnérabilité relève d’un nouveau type baptisé Toxic Agent Flow, dans lequel l’agent est amené par des prompts malveillants à exposer des données non souhaitées dans un dépôt public
- La vulnérabilité ne provient pas d’un défaut propre à l’outil, mais d’une limite architecturale, tandis que des habitudes d’usage réalistes, comme de simples politiques de confirmation d’utilisation, aggravent le risque
- Pour se défendre efficacement, il est nécessaire d’adopter des protections systémiques pour les agents, comme un contrôle granulaire des permissions et une surveillance continue de la sécurité
- Un simple alignement du modèle ne suffit pas : des mesures de sécurité au niveau système couvrant l’ensemble de l’environnement MCP et agent sont essentielles
Vue d’ensemble
Invariant a découvert une vulnérabilité extrêmement grave dans l’intégration GitHub MCP largement utilisée (14 000 stars). Cette faille permet à un attaquant de créer une GitHub Issue malveillante, de manipuler l’agent de l’utilisateur et d’exfiltrer des données d’un dépôt privé vers l’extérieur
Il s’agit du premier cas détecté par le scanner automatisé de détection de Toxic Agent Flow d’Invariant. Dans ce type de scénario, l’agent est amené à effectuer des actions non intentionnelles, entraînant des fuites de données ou l’exécution de code malveillant
Alors que le secteur déploie largement les agents de codage et les IDE, il est particulièrement important de prendre conscience de ce type d’attaque
Scénario d’attaque
-
Préparation de l’attaque
- On suppose que l’utilisateur a connecté un client MCP comme Claude Desktop à un serveur GitHub MCP
<user>/public-repo: dépôt public dans lequel n’importe qui peut créer une Issue<user>/private-repo: dépôt privé contenant des données internes à l’entreprise, etc.- L’attaquant crée une Issue malveillante (incluant une prompt injection) dans le dépôt public
- Lorsque l’utilisateur formule une demande banale comme « montre-moi la liste des issues de public-repo », l’agent récupère les issues du dépôt public et se retrouve exposé à l’injection
-
Déroulement de l’attaque
- Dès que l’agent lit l’Issue malveillante, il récupère des données du dépôt privé dans son contexte et les publie dans le dépôt public sous la forme d’une PR accessible à tous
- Ce processus est défini comme un Toxic Agent Flow, et l’analyseur de sécurité d’Invariant permet de le détecter automatiquement dans des environnements réels
Démonstration de l’attaque
- L’attaque a été reproduite à titre d’exemple avec le dépôt public (
ukend0464/pacman) et des dépôts privés - L’attaquant crée une Issue malveillante dans le dépôt public, puis la prompt injection s’exécute lorsque l’agent consulte la liste des issues de ce dépôt
- Lorsque l’utilisateur demande de l’aide à Claude 4 Opus, Claude exécute l’injection via l’intégration GitHub MCP
- Claude Desktop demande par défaut une confirmation lors de l’utilisation d’outils, mais de nombreux utilisateurs fonctionnent avec une politique « toujours autoriser » et agissent sans y prêter attention
- L’agent extrait les données du dépôt privé et les expose dans une PR publique
- L’expérience a montré la fuite d’informations sensibles, notamment des noms de projets privés, des projets de relocalisation professionnelle et des salaires
Détection des Toxic Agent Flows
- Cette vulnérabilité peut survenir même si l’outil MCP lui-même n’est pas compromis, en raison d’informations non fiables provenant d’une plateforme externe (GitHub)
- Dans les systèmes d’agents à grande échelle, l’analyse et l’atténuation manuelles de ce type de risque sont extrêmement complexes ; Invariant a donc développé une méthode de détection automatisée permettant une analyse proactive des menaces
Portée de l’impact et mesures de réponse
- Cette vulnérabilité ne se limite pas à un agent ou client particulier : elle affecte tous les agents utilisant un serveur MCP
- Il ne s’agit pas d’un défaut du code du serveur GitHub MCP lui-même, mais d’un problème de conception, qui ne peut donc pas être corrigé par un patch du serveur GitHub
- Deux stratégies de réponse essentielles sont proposées
1. Contrôle granulaire des permissions
- Dans un environnement d’intégration MCP, il faut appliquer le principe du moindre privilège afin que l’agent n’accède qu’aux dépôts strictement nécessaires
- L’autorisation traditionnelle basée uniquement sur des tokens impose d’importantes contraintes d’usage
- Une couche de sécurité dynamique à l’exécution, comme Invariant Guardrails, permet de renforcer le contrôle d’accès selon le contexte du workflow
- Exemple de politique : n’autoriser l’accès qu’à un seul dépôt par session afin d’empêcher les fuites d’informations entre dépôts
- Exemple de définition de politique :
raise Violation("You can access only one repo per session.") if: (call_before: ToolCall) -> (call_after: ToolCall) call_before.function.name in (...set of repo actions) call_after.function.name in (...set of repo actions) call_before.function.arguments["repo"] != call_after.function.arguments["repo"] or call_before.function.arguments["owner"] != call_after.function.arguments["owner"] - Il est possible de tester des politiques dans Guardrails Playground
2. Surveillance continue de la sécurité
- Au-delà des mesures préventives, il faut des outils de monitoring puissants capables de scanner en temps réel les interactions entre les agents et les systèmes MCP
- Exemple : déployer Invariant MCP-scan pour la surveillance et la détection d’anomalies
- En utilisant le mode proxy le plus récent, il est possible de rediriger uniquement le trafic MCP via un proxy pour un diagnostic en temps réel, sans modifier l’infrastructure existante
- Une surveillance complète permet de détecter les vulnérabilités, d’enregistrer les tentatives de compromission et de bloquer précocement les flux malveillants
Pourquoi l’alignement du modèle ne suffit pas
- Même les grands modèles de langage les plus récents (par ex. Claude 4 Opus) restent facilement exposés à de simples attaques par prompt injection
- Le seul apprentissage d’alignement ne permet pas d’empêcher toutes les attaques variées et dépendantes du contexte rencontrées dans des environnements de déploiement réels
- Il faut donc impérativement mettre en place, séparément du modèle, des mécanismes de sécurité et de détection contextuelle au niveau système
Conclusion
- Invariant a démontré une vulnérabilité grave du serveur GitHub MCP permettant de prendre le contrôle d’un agent via une GitHub Issue malveillante et d’exfiltrer des dépôts privés
- Cette vulnérabilité est un cas représentatif découvert par le système de détection automatisée d’Invariant, et des attaques similaires continuent de survenir dans divers environnements, y compris MCP
- L’adoption et l’exploitation sûres des systèmes MCP/agents reposent sur des scanners de sécurité dédiés comme MCP-scan et Guardrails
Références et contact
- Pour toute mise en œuvre de sécurité supplémentaire ou besoin de conseil, il est possible de contacter earlyaccess@invariantlabs.ai
Auteur :
Marco Milanta
Luca Beurer-Kellner
2 commentaires
C’est impressionnant sur le papier, mais au fond c’est simplement un problème causé par une injection de prompt combinée au fait que le MCP dispose de beaucoup trop de permissions.
Du coup, on a l’impression que cela sert surtout à promouvoir un outil permettant de contrôler de l’extérieur les permissions du MCP.
Ce serait bien de différencier les permissions que le MCP peut utiliser entre les prompts saisis depuis l’extérieur et ceux saisis uniquement en interne.
Avis Hacker News
J’ai l’impression que cette attaque n’est pas totalement comprise. Si vous donnez à Claude un jeton d’accès, alors, quelle que soit l’instruction sur son usage, Claude peut être amené à faire n’importe quoi dans la limite des permissions de ce jeton. Si vous fournissez des identifiants à un LLM, il faut partir du principe que le LLM pourra exploiter toutes les permissions associées à ces identifiants. Il faut être particulièrement prudent si les appels d’outils sont autorisés automatiquement. Cela dit, GitHub dispose de jetons d’accès à permissions fines, donc si vous n’accordez l’accès qu’à des dépôts spécifiques, l’étendue d’un éventuel abus par le LLM reste limitée. Cette attaque n’est possible que si le LLM a accès à l’ensemble du compte, et le vrai problème est déjà de donner à Claude des identifiants aussi risqués
Le point important ici, comme dans la plupart des attaques par prompt injection, est qu’on place le LLM dans un environnement où il a simultanément accès à au moins deux des trois éléments suivants : des données contrôlées par un attaquant, des informations sensibles, et des capacités d’exfiltration. Un principe de base en conception d’agents est de n’en autoriser que deux à la fois, et de concevoir le système autour de cette règle pour éviter les problèmes de sécurité. Par exemple, dès que le LLM consulte une issue créée par une personne non fiable, son contexte est déjà contaminé par des données produites par un attaquant. À partir du moment où il accède ensuite à des données sensibles, il faut désactiver des capacités comme l’accès à Internet. En suivant ce modèle, on reste en sécurité même sans jeton par dépôt. Malheureusement, MCP ne fournit aucun outil garantissant cela
Le problème, c’est que les permissions des jetons sont souvent trop larges, mais en même temps les développeurs ne veulent pas ouvrir un jeton distinct pour chaque dépôt. Ils donnent donc de larges permissions au jeton et accordent une confiance totale au LLM. Cette prudence est judicieuse, mais dans la pratique beaucoup d’acteurs de l’écosystème ne l’appliquent pas. Ce rapport est important aussi parce qu’il montre que les LLM peuvent être détournés dès lors qu’ils disposent de privilèges et de données non fiables. La solution consiste à restreindre dynamiquement le périmètre d’usage des jetons. Nous étudions cette approche dans cette liste
C’est le genre de problème qu’on peut rencontrer avec des services comme Railway. Railway demande parfois un accès à l’ensemble des dépôts GitHub même pour déployer un seul projet, alors que Netlify respecte le choix d’autoriser uniquement les dépôts voulus. GitHub devrait tout simplement bloquer l’approbation des applications qui ne respectent pas ce niveau de contrôle d’accès
C’est un phénomène qui se répète à chaque nouvelle technologie. On fait comme si les principes de sécurité de base pouvaient être ignorés dans un nouveau contexte. En réalité, même avec la dernière technologie « brillante », on ne doit jamais négliger les fondamentaux de la sécurité. Dans l’univers crypto aussi, on a revu exactement les mêmes arnaques et délits financiers du passé, simplement parce que les anciennes leçons avaient été ignorées sous prétexte que la technologie était différente
Si un chatbot interagit avec des utilisateurs, il faut supposer qu’il fera tout ce qui lui est permis dans son périmètre d’autorisation. Un chatbot n’est qu’une couche de commodité au-dessus d’une API, pas un mécanisme de sécurité en soi
Si MCP et la sécurité des agents vous intéressent, il existe plusieurs ressources sur lesquelles nous avons travaillé. Vous pouvez consulter une trace d’exécution Claude du scénario d’attaque complet (lien), un scanner de sécurité pour les connexions MCP (lien), une attaque de pollution d’outils MCP (blog), un cas d’exploitation de WhatsApp MCP (blog), Guardrails, une couche de sécurité pour agents (blog), et AgentDojo, qui évalue conjointement la sécurité et l’utilité des agents IA (blog)
Je me demande si on peut vraiment appeler ça un « exploit ». Si on donne à un agent un jeton lui permettant d’accéder à des dépôts privés, alors il y aura accès. MCP n’est qu’un serveur d’API. Il ne faut pas accorder de permissions à ce qu’on ne veut pas exposer via API
Comme beaucoup, j’ai lu les commentaires avant l’article. En lisant le contenu réel, on voit qu’une issue malveillante est déposée sur GitHub, et que cette issue contient un prompt visant à pousser le LLM à exfiltrer des données. Quand le propriétaire du dépôt déclenche l’agent, celui-ci suit ce prompt malveillant
C’est un véritable exploit qui abuse d’une erreur humaine, ou d’un excès de confiance. Le problème, c’est que des gens, emportés par le battage marketing, remettent tranquillement à un LLM un jeton GitHub privé donnant accès à tout leur compte
Le sujet est important, donc j’ai envie de pinailler un peu : tout le monde doit comprendre précisément les risques liés à l’exécution d’outils par l’IA. Aujourd’hui, les agents exécutent des outils en fonction de leur attention actuelle, c’est-à-dire de leur contexte, et cette attention est facilement influencée par les résultats des outils ou par les prompts. Or, dans les commentaires, on répète seulement l’idée simpliste selon laquelle « ça arrive parce qu’on a donné un jeton ». Et même après une bonne explication du problème, certains continuent de brouiller le débat avec un « l’utilisateur l’a autorisé ». C’est l’argument classique erroné face au problème du confused deputy. On invoque aussi la responsabilité de l’utilisateur, alors qu’en pratique le vrai problème est aussi que MCP n’assure ni contrôle d’accès de suivi ni journalisation. Pour ma part, je ne serais rassuré que si une journalisation est systématiquement possible. En plus, certains balayent la recherche en sécurité comme du simple « bon sens », alors que parler de sécurité n’est jamais inutile. Ce n’est pas parce qu’une vulnérabilité est faible qu’elle ne mérite pas d’être discutée. On peut même comparer cela à une injection SQL. Et ne pas comprendre la perspective selon laquelle on pollue indirectement le système — par exemple en injectant du contenu malveillant via une issue publique — me paraît dangereux. Enfin, je trouve dommage cette tendance à réagir uniquement sur la défensive au lieu de rester ouvert à des points de vue nouveaux
D’un point de vue sécurité, lorsqu’un LLM lit un texte provenant d’une source non fiable, il faut supposer que cette source peut manipuler le LLM pour orienter sa sortie comme elle le souhaite. Si cette sortie peut ensuite déclencher des appels d’outils, alors cette source non fiable peut, en pratique, utiliser ces outils. En cherchant des informations à ce sujet, j’ai aussi eu l’impression que la documentation Guardrails d’Invariant Labs avait une dimension marketing. C’est inquiétant de voir à quel point l’architecture est compliquée au point de nécessiter ce type de produit de sécurité. On peut aussi regretter que, si les entreprises d’IA avaient conçu leurs systèmes avec la sécurité au centre dès le départ, ce type de produit ne serait peut-être même pas nécessaire
C’est un problème facile à résoudre si on sépare correctement les entrées. Il suffit de marquer le prompt avec des balises comme <github_pr_comment>, d’indiquer explicitement que ce contenu n’est utilisé qu’en lecture seule et qu’il ne doit jamais être interprété comme une instruction. Cette attaque est en fait structurellement assez complexe. Cela rappelle les anciens problèmes de prompt injection dans les chatbots. Maintenant, MCP est à son tour concerné
Je me demande aussi s’il serait possible d’entraîner le LLM à considérer certaines portions de texte comme des données non nettoyées, impures, et à ignorer leur interprétation en tant qu’instructions
En réalité, les entreprises d’IA prennent bien en compte la sécurité dans leurs conceptions. Mais cet « exploit » n’est possible que lorsqu’on désactive les protections, avec de gros avertissements à l’appui. Par exemple, Claude Desktop demande par défaut une confirmation explicite pour chaque appel d’outil. Mais beaucoup d’utilisateurs activent « toujours autoriser » et ne surveillent plus les actions individuelles
Ce type de schéma de vulnérabilité logicielle se répète depuis toujours, et c’est à la fois amusant et absurde de le voir revenir avec chaque nouvelle technologie. Le motif « prendre une entrée utilisateur, l’interpréter comme une commande et l’exécuter dans un environnement mal défendu » n’a rien de nouveau. On l’a déjà vu avec les injections SQL, XSS, les inclusions PHP, etc., et maintenant le même scénario se répète avec les LLM
Je ne pense pas que MCP soit en soi révolutionnaire ni particulièrement vulnérable au piratage, même si j’ai par ailleurs mes propres opinions sur MCP. Cela ressemble surtout à un habillage marketing de techniques de prompt injection. Quand je conçois un système d’agent, j’applique toujours cette philosophie : « tout ce à quoi l’agent peut accéder est accessible à quiconque a accès à cet agent ». Je ne confie jamais le contrôle d’accès au LLM, et je pose clairement que la responsabilité de la sécurité des actions de l’agent relève toujours du demandeur lui-même. Du début à la fin de cet article, le vrai sujet à surveiller est : à quelles ressources réelles donne-t-on accès à l’agent ? Si vous lui donnez accès à des données e-mail et qu’un e-mail de prompt injection pousse le LLM à voler puis transmettre un jeton de sécurité, là on parle d’un vrai risque grave
On peut voir un exemple réel d’attaque et la réaction de l’agent ici. Le fait que l’agent ait totalement réussi l’attaque a quelque chose d’un peu comique
J’ai moi-même essayé l’agent de code Jules de Google la semaine dernière, et la demande de permissions GitHub OAuth exigeait un accès global à tous les dépôts et toutes les permissions du compte. Ce design est en partie dû à la commodité pour les développeurs, mais aussi au flux d’authentification GitHub OAuth lui-même. Il devrait être beaucoup plus simple d’accorder dès le départ des permissions limitées par dépôt, puis de demander des permissions supplémentaires par la suite. En pratique, on en vient à devoir créer un compte GitHub séparé juste pour n’autoriser que certains dépôts (exemple de compte). C’est très pénible. La documentation officielle GitHub recommande d’ailleurs aussi de créer ce type de machine user, mais il devrait être plus facile de définir un périmètre de dépôt par défaut. Si quelqu’un connaît une meilleure méthode, je suis preneur
J’ai l’impression que les affirmations de cet article sont très exagérées. Pour la description d’une exfiltration de données via une simple issue, en réalité il fallait que l’utilisateur effectue lui-même toute une série d’actions risquées du point de vue sécurité : configurer un serveur MCP, fournir des identifiants donnant accès aux dépôts publics et privés, autoriser le LLM à accéder à ce serveur et à lire les issues du dépôt, puis lui faire lire l’issue malveillante, avec en plus un réglage permettant de publier le résultat vers l’extérieur. Le résultat est certes mauvais, mais on ne peut pas vraiment parler ici d’une « faille de sécurité » au sens d’une attaque malveillante classique d’un tiers. C’est plutôt la conséquence du fait que l’utilisateur a lui-même fait lire des données non fiables et publier les résultats vers un endroit non fiable. Cela dit, GitHub MCP porte aussi une part de responsabilité : le fait de ne pas empêcher les traitements croisés entre dépôts publics et privés est un problème
Fondamentalement, il ne faut pas oublier qu’une consigne aussi simple que « veuillez résumer les issues » peut suffire à faire exécuter les instructions contenues directement dans une issue malveillante
L’angle marketing autour de MCP compte aussi. Le protocole lui-même devrait être cloisonné pour n’être accessible qu’à des environnements ou des utilisateurs de confiance. Le problème, c’est qu’il n’existe pas de solution standard pour définir un périmètre ou une authentification côté serveur MCP. J’ai l’impression qu’au-delà de GitHub MCP, c’est surtout l’ensemble de notre industrie qui a un problème plus fondamental dans sa manière d’utiliser et d’implémenter cela. En pratique, quand j’utilise un serveur MCP personnalisé, je transmets aussi des informations autres que l’IA, comme un ID ou un JWT, afin de bloquer les accès côté sécurité
Avec l’engouement actuel pour l’IA, la réalité est que beaucoup de gens mettent en place ce genre de configuration et de flux dangereux sans trop réfléchir. On peut évidemment dire « il ne faut pas utiliser ça comme ça », mais c’est justement pour cela qu’il faut des guardrails. Les gens prennent souvent des décisions risquées
À propos de l’idée qu’il ne faudrait pas mélanger dépôts publics et privés : dans les faits, ce sont des appels d’outils totalement distincts. Du point de vue du serveur MCP, il n’existe aucun moyen de détecter cette interaction
Je viens de remarquer que la discussion se poursuit dans ce fil HN
Comme cela a déjà été mentionné là-bas, le risque de sécurité est clair : si l’on donne à un système l’accès à des données privées tout en permettant à des utilisateurs externes d’y injecter du texte arbitraire, on revient de fait à leur donner indirectement accès à ces données privées. C’est un problème très facile à éviter en respectant les pratiques de sécurité standard
Les commentaires ont désormais été déplacés et regroupés ici
MCP n’est qu’un protocole parmi d’autres, et il existe de nombreux cas comparables, comme A2A ou des approches plus primitives. On peut aussi demander à un LLM de lire la documentation de l’API GitHub et d’utiliser directement l’API avec un jeton. Tous les LLM n’ont pas encore ce niveau de capacité, mais ils finiront par l’avoir. Sécuriser parfaitement les mécanismes d’enregistrement d’outils est, en pratique, presque impossible. La responsabilité finale en cas d’exfiltration de données repose donc en fin de compte sur le LLM. Comme les développeurs veulent gagner en productivité grâce aux LLM, il faudra soit garantir leur sûreté, soit finir par ajouter un pare-feu de sécurité sur tous les laptops. Le plus pénible, c’est qu’à l’avenir on risque même de voir des duels entre LLM, avec des « LLM qui traquent les LLM malveillants »… et qui finissent eux-mêmes exploités par d’autres LLM