- Noma Labs a découvert GitLost, une vulnérabilité d’injection de prompt indirecte dans les GitHub Agentic Workflows, qui permettait d’exposer dans un commentaire public des données de dépôts privés d’une même organisation à partir d’une simple issue ouverte sur un dépôt public
- Cette fonctionnalité compile des workflows Markdown en fichiers YAML Actions, puis un agent IA basé sur Claude ou GitHub Copilot lit les issues, appelle des outils et accède aux dépôts de l’organisation
- Le workflow vulnérable lisait le Title et le Body de l’issue lors de l’événement
issues.assigned, puis répondait viaadd-comment, tout en disposant de droits de lecture sur des dépôts publics et privés - L’attaquant n’avait besoin ni de code, ni d’accès, ni d’identifiants : il lui suffisait d’ouvrir une issue crédible sur un dépôt public ; lors des tests, le contenu des
README.mddepocettestlocala été publié dans un commentaire d’issue public - Les garde-fous de GitHub n’ont pas bloqué correctement une variante avec “Additionally” ; avec une IA agentique, il faut considérer la fenêtre de contexte elle-même comme une surface d’attaque et séparer le contenu contrôlé par l’utilisateur des instructions de confiance
La frontière de confiance visée par GitLost
- Noma Labs a découvert une vulnérabilité nommée GitLost dans les nouveaux Agentic Workflows de GitHub
- Un attaquant non authentifié pouvait publier une GitHub Issue piégée dans un dépôt public de la même organisation pour pousser l’agent à récupérer des données de dépôts privés de l’organisation
- L’attaque relève de l’injection de prompt indirecte, qui consiste à dissimuler des instructions malveillantes dans le contenu lu par l’agent IA
- Si les instructions cachées par l’attaquant sont traitées avant celles prévues par l’opérateur, des données privées peuvent être exposées dans un commentaire d’issue public visible par tous
Fonctionnement des GitHub Agentic Workflows
- Les GitHub Agentic Workflows permettent aux équipes d’écrire l’automatisation des dépôts en langage naturel
- Les workflows sont rédigés dans des fichiers Markdown
.md, puis compilés en fichiers GitHub Actions.ymlau format YAML - À l’exécution, un agent IA basé sur Claude ou GitHub Copilot agit dans le cadre des permissions configurées
- Lecture des GitHub Issues
- Appel d’outils
- Accès à d’autres dépôts de l’organisation
Conditions du workflow vulnérable
- La configuration vulnérable observée par Noma Labs devenait problématique lorsqu’elle combinait issues publiques et permissions de l’agent
- Déclenchement du workflow via l’événement
issues.assignedde GitHub - Lecture du Title et du Body de l’issue
- Publication d’un commentaire avec l’outil
add-comment - Possession de droits de lecture sur d’autres dépôts de l’organisation
- Dépôts publics
- Dépôts privés
- Déclenchement du workflow via l’événement
- L’attaquant n’avait besoin ni d’écrire du code, ni de disposer d’un accès particulier, ni d’identifiants
- La seule condition était de pouvoir ouvrir une issue sur un dépôt public d’une organisation utilisant GitHub Agentic Workflow
Déroulé de l’attaque
- Les chercheurs ont rédigé une GitHub Issue crédible donnant l’impression d’émaner d’une demande du VP Sales après une réunion client
- Une fois l’issue assignée, l’action de workflow a été déclenchée ; lors des tests, le même mécanisme fonctionnait aussi avec d’autres GitHub workflow actions
- Après l’assignation automatique de l’issue par l’automatisation GitHub, le workflow lancé par l’événement amenait l’agent à récupérer le contenu de dépôts
- L’agent a été amené à récupérer le contenu du
README.mddes dépôts suivantspocdépôt publictestlocaldépôt privé
- L’agent GitHub a ensuite publié ce contenu dans un commentaire d’issue du dépôt public, le rendant lisible par tout le monde
Contourner les garde-fous avec “Additionally”
- GitHub disposait de garde-fous limités pour empêcher ce scénario
- Noma Labs a testé à répétition plusieurs variantes comme le ferait un attaquant
- En ajoutant le mot-clé “Additionally”, le modèle ne refusait plus la demande et reconstruisait la sortie de manière inattendue
- Avec ce contournement, les garde-fous de GitHub n’ont pas fonctionné comme prévu et n’ont pas empêché la fuite de données
PoC et données exposées
- Noma Labs a publié ses constatations, le workflow de reproduction et des preuves concrètes
- Les données exfiltrées incluaient le contenu des
README.mddes dépôts suivantssasinomalabs/poc: dépôt publicsasinomalabs/remote-ping: dépôt public, absence de README confirméesasinomalabs/testlocal: dépôt privé
Des hypothèses de sécurité qui changent avec l’IA agentique
- La fenêtre de contexte de l’agent est à la fois son espace de travail et une surface d’attaque
- Tout contenu lu par l’agent peut être instrumentalisé
- Issues
- Pull Requests
- Commentaires
- Fichiers
- Les modèles de sécurité traditionnels supposent souvent que la frontière de confiance est imposée par le code
- Dans les systèmes agentiques, une partie de cette frontière de confiance est imposée par le comportement du modèle
- Comme le modèle suit par nature des instructions, l’injection de prompt devient pour l’IA agentique une vulnérabilité de même catégorie que l’injection SQL pour les applications web
- Ce type de vulnérabilité exige des stratégies et des défenses systématiques
Défenses recommandées et procédure de divulgation
- Le contenu contrôlé par l’utilisateur ne doit pas être traité comme une entrée d’instructions de confiance pour l’agent IA
- Les permissions de l’agent doivent être limitées au strict minimum nécessaire
- Un agent capable d’accéder à plusieurs dépôts devient une cible d’attaque particulièrement intéressante
- Il faut limiter ce que l’agent peut publier publiquement, notamment lorsqu’il répond au contenu d’une issue
- Les entrées utilisateur doivent être nettoyées ou isolées du contexte d’instructions avant d’être transmises au modèle
- GitLost a été divulgué de manière responsable à GitHub, et les détails de la vulnérabilité sont partagés alors que GitHub en a connaissance
1 commentaires
Avis sur Hacker News
L’analogie selon laquelle l’injection de prompt occupe, pour les IA agentiques, la même place que l’injection SQL pour les applications web me paraît étrange. Il me semble que l’injection de prompt est bien plus critique pour les LLM que l’injection SQL ne l’est pour SQL
L’injection SQL est apparue parce que les entrées utilisateur devenaient une partie de la chaîne de commande transmise au moteur SQL ; une entrée malveillante pouvait terminer la commande en cours avec des tokens de syntaxe SQL, puis ajouter sa propre commande SQL, et le moteur exécutait les deux. La solution consistait à utiliser des chaînes de commande fixes, statiques et précompilées, comme les requêtes préparées, et à n’appliquer les entrées utilisateur arbitraires que comme des données
Dans un agent, une atténuation similaire consisterait à prévoir des actions fixes comme « lire le dépôt 1 » ou « lire le dépôt 2 », et à n’utiliser l’entrée utilisateur que comme une donnée choisissant quelle action exécuter ; c’est une technique qu’on appelle déjà un menu. La différence, c’est que la valeur d’un LLM réside fondamentalement dans le fait d’aller au-delà d’un menu, alors que la valeur de SQL n’a pas besoin d’aller au-delà d’une « logique prédéfinie appliquée à des données arbitraires »
N’autoriser qu’un ensemble limité d’actions dans un agent ne traite que certains problèmes spécifiques, et ne sépare pas le code des données utilisateur ; ce n’est donc pas le même problème. Se limiter à des actions restreintes ressemble davantage à l’utilisation de permissions de base de données plus strictes. Si seuls les SQL que l’utilisateur peut de toute façon exécuter sont autorisés, l’injection SQL perd elle aussi beaucoup de son intérêt
Faire choisir dans un menu est une possibilité, mais on peut concevoir un éventail d’actions possibles plus large. Si on donne un outil d’e-mail, il peut envoyer du spam aux clients ; si on le verrouille pour ne permettre que les réponses, on réduit l’étendue des dégâts. Comme pour les vulnérabilités où des données fuitent via le rendu d’images, il faut aussi limiter l’exfiltration de données
La solution est la même. Appliquer un contrôle d’accès basé sur les rôles avec le principe du moindre privilège, et exiger une validation par un administrateur pour les actions importantes. Dans ce cas, le pire qu’un LLM puisse faire seul, c’est à peu près de produire des mots inappropriés
L’une des mesures d’atténuation est les requêtes préparées, mais une autre consiste à ne permettre à aucun utilisateur d’accéder à toute la base de données. Un utilisateur en lecture seule ne devrait pas pouvoir faire
DROP TABLE, qu’il y ait injection SQL ou nonCet agent dispose d’un accès en lecture illimité et n’a pas de notion de « destinataire » de la réponse. Si l’on intègre les droits du destinataire, il est assez simple de faire en sorte que l’accès en lecture soit automatiquement refusé. Ce n’est pas la seule solution, mais il n’est pas difficile d’imaginer une solution allant dans ce sens
L’exemple du « menu » signifie aussi que rien n’a changé. Qu’il s’agisse d’un LLM ou d’un employé humain, ce qui est autorisé n’est qu’un ensemble contrôlé et fixe d’actions. La liberté se situe surtout dans l’expression ; l’autorisation, elle, repose sur un ensemble fixe. Je ne vois pas pourquoi il faudrait aller au-delà d’un menu
Je ne vois pas en quoi c’est une vulnérabilité de GitHub. Les chercheurs ont donné à l’agent un droit d’accès à des dépôts privés, puis lui ont demandé de répondre à des questions depuis un dépôt public, donc il est logique qu’une extraction d’informations privées soit possible.
C’est comme créer une tâche CI classique ayant accès à des secrets et l’exécuter depuis une PR publique. Si vous configurez GitHub pour que du code public ou des consignes données à un LLM s’exécutent dans un contexte ayant accès à des éléments sensibles, il y aura fuite. Ce n’est pas la faute de GitHub, mais celle de la personne qui a fait la configuration.
Même en restreignant strictement la portée des jetons, l’accès aux dépôts publics reste toujours autorisé, ce qui laisse par exemple une voie d’exfiltration via les issues de dépôts publics. Pour faire ça en sécurité, il faut compléter avec un proxy MITM qui met en œuvre des contrôles plus stricts que ceux fournis par GitHub.
Les GitHub Agentic workflows devraient être la solution officielle de premier niveau à ce genre de problème, mais il semble rester du travail, que ce soit sur le modèle de sécurité ou sur l’utilisabilité sûre.
Plus de détails : https://haulos.com/blog/do-not-give-your-agent-github-access...
C’est compatible avec le développement public, et cela permettrait aussi aux personnes externes d’ouvrir des issues publiques tout en reflétant le niveau de confiance à accorder à chaque utilisateur. En y réfléchissant sérieusement, il y aurait sans doute encore plus d’options.
Pour cela, il faut un support technique du périmétrage fin et des permissions, et il faut prendre le temps d’examiner ce qu’on veut accomplir avec l’agent, ainsi que les permissions et capacités minimales nécessaires.
Le premier point finira probablement par arriver. Pour l’instant, l’usage des agents ressemble encore au Far West. Il sera intéressant de voir quelles abstractions réduiront la friction pour trouver et définir le périmètre et les permissions quand des humains conçoivent des agents, et quelles interfaces trouveront l’équilibre entre granularité et utilisabilité lorsqu’il s’agit de limiter les capacités des agents.
Le second point est depuis toujours l’obstacle central à la construction de logiciels de qualité. Prendre le temps de bien réfléchir et de bien implémenter va frontalement à l’encontre de l’approche « move fast and break things » qui consiste à lancer des agents n’importe où.
Si la réponse à une seule de ces questions est « non », alors c’est un problème. Les GitHub Workflows classiques aussi regorgent d’élévations de privilèges via des workflows déclenchés par des PR, mais c’est un autre sujet.
La vraie solution consiste à améliorer l’interface de contrôle des permissions par prompt. Il faudrait pouvoir activer et désactiver facilement une option « inclure mes dépôts privés », comme on choisit d’autoriser ou non la « recherche web ».
C’est drôle de voir les chercheurs contourner les garde-fous dont GitHub se vantait avec un simple mot comme « Additionally ». Cela montre qu’essayer d’établir une frontière de sécurité forte à l’intérieur de la fenêtre de contexte d’un LLM est voué à l’échec.
Le modèle est fondamentalement conçu pour suivre des instructions ; donc, si l’on mélange règles système et entrées utilisateur, l’instruction la plus récente ou la plus insistante finit par l’emporter.
Pourquoi la section « divulgation responsable » ne précise-t-elle pas quand cela a été corrigé, ni si GitHub l’a reconnu ou rejeté ? Il est écrit que GitLost a été divulgué de manière responsable à GitHub et que les détails sont partagés en supposant que GitHub les connaît, mais ce n’est toujours pas corrigé ?
https://github.github.com/gh-aw/reference/cross-repository/#...
Les grandes entreprises comme Microsoft ajoutent désormais de l’IA à tous leurs produits pour pouvoir prétendre être des entreprises d’IA sous la pression des investisseurs. Un peu comme Adobe l’a fait.
Les consommateurs se lassent de ces intégrations IA à moitié terminées, et j’ai l’impression qu’un point de rupture approche.
Sérieusement, tout est instantané quand on clique un peu partout, et la CI avec des runners attachés tourne à merveille. La documentation de configuration des runners pourrait être un peu plus claire, mais à part ça, tout a été d’une fluidité remarquable.
Le chiffre d’affaires existe réellement et il est impressionnant, et il remplace les revenus grand public et par siège. Le marché est encore en train de réduire les multiples du SaaS, et je pense que ce jugement est correct. Si l’on isole le chiffre d’affaires dans les rapports trimestriels, on voit une grande histoire de croissance issue d’une efficacité réelle.
Je ne comprends pas pourquoi une action exécutée dans le contexte d’un dépôt public disposait d’un accès à un dépôt privé. En regardant le workflow, on dirait qu’il utilise le
github token, qui ne donne normalement pas de droits sur les dépôts privésOu alors l’agent lui-même avait somehow des privilèges plus élevés ? Si c’est le cas, c’est une mauvaise configuration de l’agent. On sait déjà qu’il ne faut pas croire qu’un agent garantisse quoi que ce soit
Ce billet se lit comme du marketing Noma. Il y a un nom mignon, un logo, un titre putaclic, et même un ton dramatique qui semble viser un lectorat non technique
Si l’on regarde la vulnérabilité réelle, elle revient à ceci : si l’on donne des données privées à un LLM et qu’on laisse n’importe qui interagir avec lui, ces données peuvent fuiter. C’est une évidence
Ces gens se plaindront d’avoir donné à un LLM des droits d’écriture sur tout le disque et qu’il ait effectué une opération destructrice
Si l’on ne veut pas qu’un agent IA lise des dépôts privés, il suffit de ne pas lui donner d’accès aux dépôts privés. Ce n’est pas un problème de contournement de permissions, mais un problème de prompt injection, et cela ne peut pas être résolu de manière fiable au niveau de l’agent
Soit c’est un problème déjà résolu, soit GitHub ne l’a pas encore corrigé et, entre-temps, des acteurs malveillants tenteront d’exploiter des dépôts vulnérables
Comme le nombre de dépôts est élevé, il existe une probabilité non nulle qu’une fuite se produise. Mais, comme pour les victimes d’arnaques, presque personne n’admettra avoir subi une fuite