Le rapport de bug a exécuté la commande
L'agentjacking, divulgué par Tenet Security en juin 2026, ne nécessite ni logiciel malveillant ni accès à votre infrastructure. Un attaquant dépose une fausse erreur dans votre projet Sentry à l'aide d'une clé publique en écriture seule, y dissimule des instructions, et attend. Lorsque vous demandez à votre agent de codage de corriger le problème, il lit le texte de l'attaquant comme une consigne et l'exécute avec vos identifiants. Tenet a recensé au moins 2 388 projets exposés et un taux de réussite de 85 % sur Claude Code, Cursor et Codex. Bromure Agentic Coding exécute tout ce parcours lecture-puis-exécution dans une VM Linux jetable, évalue le texte récupéré avant que l'agent n'agisse, et ne laisse au voleur d'identifiants que des leurres.
Vous avez demandé à votre agent de codage de corriger une erreur. Il a ouvert le gestionnaire de tickets, lu le premier résultat, et fait ce qu'il disait. Le problème, c'est que n'importe qui sur Internet pouvait écrire cette erreur — et celle que votre agent a lue avait été écrite pour être obéie. Aucun logiciel malveillant n'a été déposé. Aucun serveur n'a été compromis. Un rapport de bug a exécuté une commande sur votre machine.
Le 12 juin 2026, les chercheurs de Tenet Security — Ron Bobrov, Barak Sternberg et Nevo Poran — ont publié une attaque qu'ils appellent Agentjacking, via l'AI Safety Initiative de la Cloud Security Alliance. Elle n'utilise ni courriel d'hameçonnage, ni paquet empoisonné, ni mot de passe volé. Elle utilise un rapport de bug. Plus précisément, elle exploite le fait qu'un agent de codage à qui l'on demande de « corriger les tickets Sentry ouverts » va lire un rapport d'erreur et traiter son contenu comme des instructions.
Le point de départ, c'est une chose que la plupart des applications web distribuent volontairement. Un DSN Sentry — la clé qu'un site utilise pour signaler ses propres plantages à Sentry, la plateforme de suivi des erreurs — est un identifiant public en écriture seule. Il est livré dans le JavaScript côté client de la page, et le point d'entrée d'ingestion de Sentry accepte par conception des requêtes POST non authentifiées vers ce DSN. C'est ainsi que l'onglet de votre navigateur signale un plantage sans avoir à se connecter. Cela signifie aussi que quiconque lit le code source de votre page peut envoyer des événements à votre projet Sentry. Tenet les a recherchés et a trouvé 71 DSN injectables parmi le premier million de sites web, et au moins 2 388 organisations aux DSN exposés à l'échelle de tout Internet.
Comment un rapport de plantage devient une commande
L'attaquant prend un DSN qu'il a trouvé et y envoie par POST un événement d'erreur fabriqué. L'événement ressemble à un plantage ordinaire, sauf que le champ message et les clés de contexte sont rédigés en markdown — des titres, des blocs de code, une section qui se lit comme une « Résolution » — mis en forme pour être visuellement et syntaxiquement impossibles à distinguer des propres modèles de diagnostic de Sentry. Cela reste dans la liste des tickets du projet comme n'importe quelle autre erreur non résolue.
Puis l'attaquant vous attend. Lorsqu'un développeur demande à son agent de codage d'examiner les tickets Sentry non résolus, l'agent interroge Sentry — généralement via le serveur MCP de Sentry, le connecteur standard qui permet à un agent d'extraire des données d'un outil externe — et récupère l'événement. Comme le dit Tenet, l'agent « reçoit la réponse et agit en conséquence, exactement comme le ferait un développeur ». La réponse ne porte aucun signal indiquant que son contenu a été rédigé par un attaquant plutôt que par le moteur d'exécution de l'application elle-même. La « Résolution » dit d'exécuter une commande. L'agent l'exécute, avec les privilèges propres du développeur, sur la machine propre du développeur.
Tenet a signalé un taux de réussite de 85 % sur les agents qu'ils ont testés — Claude Code, Cursor et Codex, les outils vers lesquels la plupart des développeurs se tournent. Leur commande de démonstration est repartie avec des variables d'environnement, des identifiants AWS, des jetons OAuth GitHub et GitLab, des jetons de registre npm, la configuration Docker, des jetons de cluster Kubernetes et des secrets de pipeline CI/CD. Sentry, informé de la faille le 3 juin, a refusé de corriger le comportement sous-jacent — c'est, selon ses termes, techniquement indéfendable — et a ajouté un filtre de contenu global qui bloque une chaîne de charge utile spécifique.
Pourquoi toutes les défenses existantes sont passées à côté
L'agentjacking compte non pas pour l'ingéniosité de la charge utile, mais parce que rien dans une pile de sécurité normale ne se déclenche. Il n'y a aucun malware sur le disque qu'un agent de terminaison pourrait attraper. Il n'y a aucune connexion inhabituelle que la surveillance des identités pourrait signaler. Il n'y a aucune connexion sortante d'un processus qui n'aurait aucune raison d'en établir une — l'agent est censé parler à Sentry, et les identifiants du développeur sont censés fonctionner. Chaque étape de la chaîne est une action autorisée réalisée avec un accès légitime. Comme le dit Tenet, l'attaque ne viole aucune politique et ne franchit aucun seuil d'anomalie.
C'est le même mur que le reste de la sécurité agentique ne cesse de heurter. Une liste d'interdiction de commandes perd face au shell qui réécrit la commande. Un espace de travail de confiance perd face aux serveurs qu'il lance en silence. Une revue de sécurité que l'agent effectue pour vous devient ce qui vous attaque. L'agentjacking est la version où l'entrée empoisonnée arrive par un outil que vous aviez raison de croire, transportant des données que vous aviez toutes les raisons de lire. Le serveur MCP de Sentry a parfaitement fait son travail. Le problème, c'est que « récupère l'erreur et agis en conséquence » et « récupère les instructions de l'attaquant et agis en conséquence » sont, pour l'agent, la même phrase.
Les propres recommandations de Tenet pointent vers la forme du correctif : exécuter l'agent dans un bac à sable avec une sortie réseau restreinte, traiter tout ce qu'un serveur MCP renvoie comme une entrée potentiellement adverse, et cesser de laisser une chaîne récupérée devenir une commande sans frontière entre les deux. Cela décrit une architecture, pas un correctif.
Où Bromure trace la ligne
Bromure Agentic Coding n'essaie pas d'apprendre à l'agent quels rapports de bug croire. Il change ce qu'un rapport cru peut atteindre. Chaque agent que Bromure exécute — Claude Code, Codex, Grok Build — s'exécute à l'intérieur d'une VM Linux jetable sur votre Mac, et non sur macOS lui-même. Ainsi, lorsque l'agent récupère l'événement Sentry empoisonné et fait exactement ce que Tenet a observé ces agents faire, plusieurs choses sont déjà vraies.
Premièrement, le texte récupéré est lu par un détecteur avant de devenir un
plan. L'agentjacking est une attaque de lecture avant d'être une attaque
d'exécution : tout l'exploit repose sur l'ingestion par l'agent de la
« Résolution » de l'attaquant et son traitement comme une consigne. C'est
précisément l'autorité non fiable que Bromure surveille — la même classe
qu'un CLAUDE.md malveillant ou un AGENTS.md empoisonné. La détection
d'injection de prompt sur l'appareil de Bromure évalue le contenu que l'agent
lit face à des modèles locaux qui ne quittent jamais le Mac, plus un scanner
déterministe pour les astuces d'Unicode invisible. Un rapport de plantage
dont la « correction » est une commande shell qui lit vos jetons est
exactement le cas que ce détecteur existe pour signaler.
Deuxièmement, la commande s'exécute dans une boîte que vous jetez. Supposons que le leurre soit assez bien formulé pour échapper à l'évaluateur et que la commande s'exécute. Elle s'exécute dans la VM. L'« accès porte dérobée persistant » du modèle de menace de Tenet n'a rien où persister : réinitialisez le profil à sa base et le script déposé, la clé SSH ajoutée, la tâche planifiée — tout cela a disparu. Rien de ce que la commande a fait ne survit à la fermeture de la fenêtre.
Troisièmement, il n'y a aucun véritable identifiant à voler. Toute la
liste du butin de la démonstration — clés AWS, jetons GitHub et GitLab,
identifiants npm et Docker, secrets Kubernetes et CI/CD, variables
d'environnement — est ce que Bromure garde hors de la boîte dès le départ.
Bromure injecte des valeurs factices (brm_…, un ~/.kube/config
synthétique, des jetons cloud et de registre jetables) dans la VM et ne
réintroduit les vrais que sur l'hôte, dans le proxy, sur le chemin de sortie
vers la véritable API. La commande fouille l'environnement et le disque et ne
trouve que des leurres. Tout ce qu'elle expédie au serveur de l'attaquant
est un sac de chaînes qui n'authentifient rien.
Quatrièmement, l'exfiltration est visible. L'attaque de Tenet se termine par la sortie des jetons volés de la machine. Bromure fait passer le trafic de la VM par un proxy hôte, de sorte que la connexion au serveur de l'attaquant apparaît dans le Journal de sécurité comme un trafic sortant que vous pouvez voir — et non un rappel silencieux depuis un portable que vous pensiez propre. La « sortie réseau restreinte » que Tenet recommande est l'endroit où l'agent vit déjà.
Ce que cela délimite vraiment
L'isolement et l'évaluation sont du confinement, pas un remède pour un agent trop confiant. Il vaut la peine d'être précis sur ce que Bromure change ici et ce qu'il ne change pas.
Le rapport arrive quand même
Bromure ne corrige pas la conception du DSN de Sentry ni n'empêche un attaquant de déposer un plantage empoisonné — cette clé publique en écriture seule est la frontière que Sentry doit tracer, et ils ont refusé de le faire. Ce que Bromure change, c'est ce qui se passe après que l'agent a lu le rapport : où la commande s'exécute et ce qu'elle peut atteindre.
La détection est un filet, pas un mur
L'évaluation d'injection sur l'appareil signale une résolution du type « exécutez ceci pour corriger » plus souvent qu'à son tour, mais un auteur soigneux peut formuler un leurre pour échapper à un scanner unique. Traitez le détecteur comme une couche ; le confinement — une boîte jetable avec de fausses clés et une sortie journalisée — est ce qui tient quand un détecteur échoue.
La substitution couvre les secrets que vous configurez
L'échange par leurre protège les identifiants que vous mettez dans un profil : clés de modèle, jetons git et cloud, jetons de registre et de cluster, clés SSH. Un jeton qu'un script écrit sur le disque en cours d'exécution, ou une session que vous établissez à la main dans la boîte, n'est que de la donnée. Gardez les secrets dans le broker, pas dans l'espace de travail.
L'isolement n'est pas une raison de tout exécuter automatiquement
Une VM jetable réduit le rayon d'explosion ; elle ne rend pas la revue inutile. Pour les actions qui atteignent l'extérieur de la boîte — ouvrir une pull request, pousser vers un dépôt distant — l'étape de confirmation garde toute sa place. Le confinement abaisse les enjeux d'une erreur ; il ne les supprime pas.
La découverte de Tenet n'est pas qu'une plateforme a un bug. C'est que le mécanisme de confiance sous-jacent — un agent qui traite une chaîne récupérée comme un fait et une « Résolution » comme un plan — est partagé par tout outil qui connecte un agent au monde extérieur, et il ne sera pas corrigé ce trimestre. Sentry est le messager ; le prochain sera un ticket Jira, un commentaire Linear, une revue de code laissée par un inconnu. Votre agent va lire quelque chose qu'un attaquant a écrit, et à un taux de réussite de 85 % il fera parfois ce qui est dit. La question n'est pas de savoir s'il se fera un jour berner. La question est de savoir ce qui s'exécute quand cela arrive : votre machine, vos vrais jetons, et une prise de pied qui reste — ou une boîte Linux que vous pouvez jeter, avec des leurres à l'intérieur et la sortie enregistrée. Bromure en fait la seconde.