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

L'agent n'a jamais quitté le bac à sable

Le 20 juillet 2026, Pillar Security a publié sept évasions de bac à sable touchant Cursor, le Codex CLI d'OpenAI, le Gemini CLI de Google et Antigravity. Aucune n'a brisé le bac à sable. L'agent est resté à l'intérieur, a respecté chaque règle et a écrit un fichier ordinaire — une configuration de hook, un environnement virtuel, un réglage git — qu'un outil de confiance sur l'hôte a lu et exécuté de lui-même. Le bac à sable a tenu ; l'évasion a eu lieu quand même. Bromure Agentic Coding trace la ligne là où ce coup n'a nulle part où atterrir.

Chaque histoire d'évasion précédente parlait d'un mur qui cède. Celle-ci parle d'un mur qui tient, et de l'évasion qui a lieu quand même. L'agent a obéi au bac à sable, a écrit un fichier qu'il était autorisé à écrire, et un programme de confiance de l'autre côté du mur a ramassé ce fichier et l'a exécuté.

Un agent de code s'exécute dans un bac à sable afin que, lorsqu'il fait quelque chose d'imprudent — et il le fera, parce qu'il lit du texte non fiable toute la journée et en croit la majeure partie —, les dégâts s'arrêtent au mur du bac à sable. C'est la promesse. Le 20 juillet 2026, Pillar Security a publié sept façons dont la promesse se brise, touchant quatre des agents les plus utilisés : Cursor, le Codex CLI d'OpenAI, le Gemini CLI de Google et Antigravity. BleepingComputer l'a couvert la même semaine.

Sept n'est pas le nombre surprenant. Ce que les sept ont en commun, c'est ceci : selon les mots mêmes des chercheurs, « dans presque tous les cas, l'agent n'avait pas besoin de briser le bac à sable directement. Il lui suffisait d'écrire quelque chose qu'un composant de confiance hors du bac à sable exécuterait, chargerait, analyserait ou traiterait comme sûr plus tard. »

Le coup : rester à l'intérieur, écrire un fichier, laisser l'hôte l'exécuter

Pensez à ce que contient réellement le bac à sable d'un agent de code. Il contient le processus de l'agent — la chose qui exécute les décisions du modèle. Il ne contient pas les fichiers de l'agent, parce que tout son travail consiste à écrire des fichiers : sources, configurations, scripts de build. Ces fichiers atterrissent sur le même disque que celui que vos autres outils lisent. Et vos autres outils ne sont pas dans un bac à sable. L'extension Python de votre éditeur n'est pas dans un bac à sable. Votre git n'est pas dans un bac à sable. Le démon Docker n'est pas dans un bac à sable. Ils font confiance à ce qui est sur le disque, parce que jusqu'à récemment la seule chose qui écrivait sur ce disque, c'était vous.

Donc l'agent ne touche jamais au mur. Il écrit un fichier exactement là où il est censé le faire, et attend que quelque chose de l'autre côté le lise. Les sept évasions de Pillar sont sept versions de ce même coup :

Une configuration de hook qui s'exécute

Dans Cursor, l'agent écrit une configuration de hook .claude d'espace de travail. Les hooks sont censés exécuter des commandes lors d'événements de l'éditeur — donc la commande de ce fichier s'exécute, hors bac à sable. Attribuée CVE-2026-48124, corrigée dans Cursor 3.0.0.

Un interpréteur Python, remplacé

L'agent modifie l'interpréteur à l'intérieur de l'environnement virtuel d'un projet. L'extension Python de l'éditeur — hors du bac à sable — l'invoque plus tard, et le binaire remplacé s'exécute. Suivi sous GHSA-p9g2-cr55-cw9c.

Une commande git validée par son nom

La liste d'autorisation de « commandes sûres » du Codex CLI a laissé passer une invocation git parce que le nom paraissait bénin, sans lire les arguments qui la rendaient dangereuse. Corrigé dans Codex CLI 0.95.0.

Un démon qui est une seconde machine

Sur plusieurs agents, le socket Docker était accessible depuis l'intérieur du bac à sable. Un démon local privilégié est tout un second endroit où exécuter du code, situé juste hors de la frontière. Suivi sous GHSA-v4xv-rqh3-w9mc.

Antigravity en a ajouté deux autres de la même forme — une liste de refus Seatbelt de macOS qui a manqué un cas, et une configuration de tâche VS Code que l'agent a écrite et que l'IDE a plus tard exécutée de lui-même. Les deux ont été jugées plus difficiles à réaliser, mais elles font écho au reste.

Le bac à sable — tientProcessus agentobéit à chaque règle,ne touche jamais au murIl n'a le droitque d'écrire un fichier…Disque partagéconfig hook ·virtualenv · gitréglage · tâcheordinaire, autoriséL'hôte — hors bac à sableL'outil de confiance le lit :Extension Python · git ·démon Docker · lanceur…et l'exécute, hors de la boîte.Le code s'exécute comme vous.Sept évasions, quatre agents — le bac à sable n'est jamais percé ; son disque partagé l'est.
L'évasion qui n'en est pas une. L'agent reste à l'intérieur du bac à sable et respecte chaque règle (à gauche). Il écrit un fichier ordinaire et autorisé — une configuration de hook, un interpréteur d'environnement virtuel, un réglage git, une définition de tâche — sur le disque partagé. Un outil de confiance sur l'hôte qui n'est pas dans un bac à sable — l'extension de l'éditeur, git, le démon Docker, le lanceur de tâches de l'IDE — lit ce fichier dans le cadre de son travail normal et exécute ce qu'il nomme (à droite). La commande s'exécute hors du bac à sable sans que celui-ci soit jamais touché.

Pourquoi corriger chacune ne referme pas la forme

Chacune de celles-ci a reçu un correctif, et ce sont de bons correctifs. Cursor a publié la 3.0.0, le Codex CLI a publié la 0.95.0, le socket Docker a été verrouillé. Si vous utilisez ces outils, mettez-les à jour. Mais regardez ce qu'un correctif doit faire ici. Il doit trouver chaque fichier que l'agent peut écrire et qu'un autre programme traite comme des instructions — configurations de hook, chemins d'interpréteur, métadonnées git, définitions de tâches, règles de lint, quoi que ce soit qui sortira le trimestre prochain — et traiter chacun comme un cas particulier. C'est une liste de refus, et Pillar cite les listes de refus comme le premier de quatre modes d'échec récurrents parce qu'« un profil de bac à sable qui part de "tout autoriser par défaut" doit se souvenir de chaque opération dangereuse que l'OS expose ». L'OS ne cesse d'ajouter des opérations. La liste n'est jamais terminée.

La raison plus profonde est une phrase du rapport qui se lit comme une définition : « Si un agent peut écrire les entrées futures des systèmes, il n'a jamais été dans un bac à sable au départ. » Une frontière tracée autour du processus de l'agent, sur une machine où l'agent partage un disque et un ensemble de démons de confiance avec tout le reste, est tracée autour de la mauvaise chose. Le rayon d'action, écrivent-ils, « n'est pas le processus de l'agent ; il inclut tout ce que l'agent peut écrire et à quoi l'hôte fait ensuite confiance ». Sur l'ordinateur portable d'un développeur, c'est presque tout.

Où Bromure trace la ligne

Bromure Agentic Coding n'essaie pas d'énumérer les fichiers dangereux, ni d'apprendre au bac à sable ce que sont les hooks, les environnements virtuels et les lanceurs de tâches. Il déplace la frontière. L'agent de chaque profil s'exécute dans une VM Linux jetable sur Apple Silicon, à un hyperviseur de distance de macOS. Dans ce modèle, l'« outil de confiance hors du bac à sable » — l'extension Python de votre éditeur, votre git, le démon Docker, le lanceur de tâches de l'IDE — n'est pas de l'autre côté d'un mur de permissions. Il est de l'autre côté d'un hyperviseur, et il ne lit pas du tout le disque de la VM.

C'est toute la différence. Le coup de Pillar a besoin de deux choses au même endroit : un disque que l'agent peut écrire, et un programme de confiance qui lit ce disque. Placez le disque de l'agent dans la VM et la seconde chose disparaît. L'agent peut écrire une configuration de hook, remplacer un interpréteur d'environnement virtuel, planter une définition de tâche — chaque fichier des sept évasions — et il n'y a aucun outil hôte non isolé qui surveille ce système de fichiers pour le ramasser. Ce qui s'exécute s'exécute dans la boîte, en tant qu'utilisateur ubuntu jetable, dans une machine qui ne contient rien.

Bac à sable de processus — une machineAgent (en bac à sable)écrit un fichierde config autoriséOutils hôtes (nonisolés)le lisent, l'exécutentDisque partagé — lu des deux côtésLa commande s'exécute comme vous —clés réelles, code, cloud à portéeLa frontière entourait le processus.Le disque était partagé avec l'hôte.Bromure Agentic Coding — VM hyperviseurVM jetableAgentécrit le mêmefichier de configLe disque vitdans la boîteaucun outil hôtene le litS'exécute en ubuntucontre des leurres brm_…Sortie filtréeau proxy de l'hôteAucun outil hôte ne surveille son disque.Fermez la session et tout se réinitialise.
Les mêmes sept fichiers, deux frontières. Sur une configuration normale (à gauche), le bac à sable de l'agent n'entoure que le processus ; le fichier qu'il écrit atterrit sur un disque que les outils hôtes non isolés lisent, et la commande s'exécute comme vous, à côté de vos clés et de votre code. Sous Bromure Agentic Coding (à droite), la frontière est un hyperviseur autour de toute la VM : le disque de l'agent est dans la boîte, aucun outil hôte ne le lit, et tout ce qui s'exécute s'exécute en tant qu'utilisateur jetable contre des identifiants leurres, chaque requête sortante étant filtrée au proxy de l'hôte. Fermez la session et la boîte se réinitialise.

Il y a une seconde moitié aux évasions qui mérite d'être nommée, parce que Bromure y répond aussi. Supposons qu'un fichier écrit par l'agent finisse bien par être exécuté par un outil à l'intérieur de la VM — le but d'exécuter du code est généralement de voler quelque chose ou d'atteindre quelque part. Les deux sont des impasses ici. Le code vise les identifiants qui rendent le voyage rentable, la clé Anthropic, les clés AWS, le jeton GitHub, et ne trouve que des leurres : un courtier d'identifiants sur l'hôte injecte des espaces réservés comme brm_…, un kubeconfig synthétique et une clé SSH jetable, et n'échange la vraie valeur qu'à la frontière réseau, sur des requêtes vers des destinations que vous avez déjà approuvées. Et l'étape sortante — exfiltrer le butin, ou atteindre un second hôte — traverse le proxy de l'hôte, où la vraie destination est filtrée à la sortie et où une action destructrice contre les API cloud et git que le profil expose, une suppression, un drop ou une résiliation, rencontre un garde-fou qui peut la refuser, quoi que l'agent ait été amené à faire.

Avant tout cela se trouve la couche qui saisit ces évasions à leur racine. Chacune commence par une injection — une instruction malveillante dans un fichier ou un résultat d'outil que l'agent lit, lui disant d'écrire la configuration empoisonnée en premier lieu. Bromure évalue ce contenu non fiable avec un détecteur d'injections sur l'appareil avant que le modèle n'agisse dessus. Il en attrape la plupart, et une charge suffisamment inédite peut encore échapper à un classifieur, ce qui est précisément la raison pour laquelle il se tient devant la boîte jetable plutôt qu'à sa place.

La frontière était autour de la mauvaise chose

La leçon durable de la semaine de Pillar n'est pas une liste de sept bugs à corriger. C'est que mettre en bac à sable le processus de l'agent, sur une machine où ce processus partage un disque et un ensemble d'outils de confiance avec tout ce que vous possédez, trace la ligne autour de la mauvaise chose. L'agent n'a pas besoin de s'évader s'il peut écrire les entrées de quelque chose qui est déjà dehors.

Corriger les fichiers connus est juste, et vous devriez le faire. Mais c'est une course contre chaque format futur qu'un outil hôte décidera de croire, et cette course ne finit pas. Bromure Agentic Coding en sort. Il suppose que l'agent sera amené à écrire le fichier empoisonné, et fait en sorte que, lorsqu'un outil le lit, cet outil soit à l'intérieur d'une boîte jetable avec des leurres pour les secrets et un filtre sur le fil — pas votre ordinateur portable, qui détient vos clés. C'est la différence entre un mur que vous devez sans cesse corriger et une ligne tracée un niveau plus bas, là où l'écriture n'a aucun lecteur. Installez-le et donnez à votre agent une machine qui n'est pas la vôtre à perdre.