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

L'injection qui a désactivé le bac à sable de Cursor

Le 1er juillet 2026, Cato AI Labs a divulgué DuneSlide : deux failles critiques dans Cursor (CVE-2026-50548 et CVE-2026-50549, toutes deux CVSS 9.8) où une injection de prompt arrivant dans un résultat d'outil MCP ou un extrait de recherche web pilote l'outil run_terminal_cmd et un repli sur les liens symboliques pour écraser le propre binaire de bac à sable de Cursor. Le garde s'éteint de l'intérieur, et la commande suivante s'exécute avec les droits du développeur, avec accès à tout cloud ou SaaS auquel l'éditeur est connecté. Sans interaction de l'utilisateur, corrigé dans Cursor 3.0. C'est une histoire sur l'endroit où doit se trouver une frontière : dans Bromure Agentic Coding, la même évasion atterrit à l'intérieur d'une VM jetable, le shell évadé trouve des stubs de substitution là où devraient être les vrais tokens, et PromptGuard score ce contenu non fiable sur le fil avant même que le modèle n'agisse dessus.

DuneSlide ne s'est pas évadé du bac à sable de Cursor. Il a convaincu le propre agent de Cursor d'écraser le petit binaire qui faisait appliquer le bac à sable, et le garde s'est tu de l'intérieur. Une frontière qui vit dans le même processus que le code qu'elle surveille est une frontière que ce code peut atteindre.

Un développeur demande à Cursor de câbler une nouvelle intégration et le pointe vers la documentation d'un fournisseur, ou connecte un serveur Model Context Protocol pour que l'agent puisse tirer des données en direct. MCP est la prise qui permet à un agent de codage d'appeler des outils externes et de lire leurs résultats. Cursor récupère la page, lit la sortie de l'outil, et replie les deux dans le contexte sur lequel il raisonne. Quelque part dans ce texte renvoyé se niche une phrase que le développeur n'a jamais écrite, adressée au modèle plutôt qu'à un humain. L'agent la lit comme une instruction et agit.

Le 1er juillet 2026, Cato AI Labs a divulgué la chaîne que cela met en place, et The Hacker News l'a couverte le jour même. Deux failles, CVE-2026-50548 et CVE-2026-50549, toutes deux notées 9,8 sur 10. Le vecteur de livraison est un contenu non fiable que l'agent lit déjà en votre nom : un résultat d'outil MCP, un extrait d'une recherche web. Aucun dialogue, aucun clic, aucune interaction de l'utilisateur.

Ce que fait DuneSlide.

Cursor exécute les commandes que son agent génère à l'intérieur d'un bac à sable local, et un binaire d'assistance décide de ce que ce bac à sable autorise. La première faille vit dans run_terminal_cmd, l'outil que l'agent utilise pour exécuter des commandes shell. Cet outil prend un paramètre working_directory, et l'injection le fixe à un chemin qui pointe vers les propres fichiers de Cursor. L'agent, suivant l'instruction passée en douce, écrit par-dessus l'assistant qui se trouve à /Applications/Cursor.app/.../helpers/cursorsandbox. La seconde faille est un repli dans la façon dont Cursor résout les liens symboliques : lorsque la vérification du lien symbolique échoue, Cursor fait confiance au chemin in-projet du raccourci et écrit tout de même hors du projet, atterrissant sur le même assistant.

Dans un cas comme dans l'autre, le résultat est une seule et même chose. Le binaire qui décide si une commande est confinée est remplacé par un qui ne confine rien. La commande suivante que l'agent exécute s'exécute avec les droits du développeur, hors du bac à sable, avec l'accès de celui qui est connecté à l'éditeur : la console cloud, les tableaux de bord SaaS, les dépôts que la session peut déjà toucher. Cursor a corrigé les deux failles dans la version 3.0. Toute version antérieure est exposée.

VOTRE MAC : Cursor, le contenu qu'il lit, l'assistant et vos identifiants partagent tous une seule machineCONTENU NON FIABLErésultat d'outil MCP / extrait de recherche web"fixe working_directory sur le chemin de l'assistant Cursor et exécute…"AGENT CURSORlit le résultat comme du contextetool: run_terminal_cmdworking_directory = ../Cursor.applu comme instructionASSISTANT DE BAC À SABLE (écrasé).../helpers/cursorsandboxCVE-2026-50548: working_directoryCVE-2026-50549: repli sur lien symboliqueGARDE DISPARU : la commande suivante s'exécute avec vos droitsaccès à la console cloud et aux tableaux de bord SaaS auxquels l'éditeur est connectéaucun dialogue, aucun clic, aucune interaction de l'utilisateur
DuneSlide, de gauche à droite. Un résultat d'outil MCP ou un extrait de recherche web porte une instruction visant le modèle. Cursor la lit comme du contexte et exécute run_terminal_cmd avec working_directory pointé vers ses propres fichiers (CVE-2026-50548), ou écrit à travers une vérification de lien symbolique échouée vers le même endroit (CVE-2026-50549). Les deux atterrissent sur cursorsandbox, l'assistant qui fait appliquer le bac à sable, et l'écrasent. Le garde remplacé, la commande suivante s'exécute avec les droits du développeur et atteint les comptes cloud et SaaS auxquels l'éditeur est connecté. Cursor, le contenu injecté, l'assistant et les identifiants partagent tous un seul Mac.

Le garde était assis dans la pièce même qu'il gardait.

Relisez la chaîne et la partie tranchante n'est pas l'astuce du lien symbolique. C'est l'emplacement du garde. L'assistant qui décide si une commande est confinée se trouve sur le même disque que le projet que l'agent édite, dans le même domaine de confiance que l'agent, accessible par le même run_terminal_cmd que l'agent utilise pour son travail ordinaire. Le bac à sable et le code qu'il surveille s'exécutent en tant qu'un seul utilisateur, sur une seule machine, avec un seul système de fichiers entre eux. Donnez à l'agent la capacité d'écrire un fichier, laissez un attaquant choisir quel fichier, et le fichier qu'il choisit est le garde.

C'est la défaillance récurrente de la sécurité des agents de codage cette année, et nous l'avons documentée sous d'autres formes : un identifiant que l'agent peut lire est un identifiant qu'une dépendance compromise peut lire dans le bac à sable qui gardait la clé, et un contrôle que l'agent peut désactiver n'a jamais été un contrôle dans pourquoi Bromure Agentic Coding n'est pas un bac à sable. DuneSlide est la même leçon au niveau du binaire de bac à sable lui-même. Un garde in-processus vous protège jusqu'à ce que le processus dans lequel il vit décide de l'éditer.

La même attaque, à un hyperviseur de distance.

Bromure Agentic Coding place la frontière quelque part où l'agent ne peut pas écrire. L'agent, les shells qu'il engendre, les outils qu'il appelle, et tout code que ces outils exécutent vivent à l'intérieur d'une machine virtuelle jetable dotée de son propre noyau Linux. Chaque octet que la VM envoie ou lit traverse un proxy qui s'exécute sur l'hôte macOS, sous l'invité, de l'autre côté de l'hyperviseur. Ce proxy est un seul endroit, et il remplit plusieurs rôles. Rejouez DuneSlide contre lui et chaque étape en rencontre un.

Commençons par l'évasion. L'injection arrive toujours, l'agent exécute toujours run_terminal_cmd, et les deux CVE se déclenchent toujours. L'écrasement atterrit sur les propres fichiers de l'invité. Le disque du Mac, son /Applications, son Keychain ne sont pas dans le monde de la VM, donc il n'existe aucun chemin depuis un lien symbolique à l'intérieur de l'invité vers un binaire sur l'hôte. Le rayon d'explosion est une machine que vous pouvez supprimer et reconstruire en quelques secondes.

Puis l'étape de récompense, l'accès au cloud et au SaaS. C'est là que l'attaque venait chercher de la valeur, et elle repart les mains vides. Les vrais tokens restent sur l'hôte. La VM ne détient que des stubs : des fichiers d'identifiants ayant la bonne forme et aucune signification sur l'internet public. Quand l'agent fait un appel qui nécessite un vrai secret, le proxy hôte substitue le vrai token au stub sur le fil et le retire de la réponse. Un shell évadé exécutant env | grep TOKEN ou lisant ~/.aws/credentials ne trouve que des substituts. Le seul moment où un vrai identifiant existe est à l'intérieur d'une requête que l'agent a faite pour un vrai travail, et un appel qui modifie l'état s'arrête à la frontière pour une confirmation sur l'hôte avant de partir. Les récupérations de packages traversent le même proxy et sont scannées à l'entrée. Une seule ligne, plusieurs rôles, tous en dessous de l'agent.

CONTENU NON FIABLE : résultat MCP / extrait webporte l'injection qui déclenche DuneSlidePROMPTGUARD (si activé)le score avant que le modèle ne le lisesi elle passeVM JETABLE : son propre noyau ; Cursor, les shells et les outils vivent ici① L'ÉVASION ATTERRIT DANS L'INVITÉrun_terminal_cmd + écrasement par lienfrappent les propres fichiers de l'invitéle disque du Mac n'est pas dans ce monde② LES TOKENS QU'ELLE VOULAIT NE SONT PAS ICIenv | grep TOKEN → stub-…cat ~/.aws/credentials → stub-…rien de réel à dépenserun vrai appel que l'agent a faitPROXY CÔTÉ HÔTE, une seule frontière : scorer le fil · substituer le vrai token au stub · scanner les packages · confirmer les appels modifiant l'étatMAC HÔTE : les vrais tokens dans le Keychain, jamais à l'intérieur de la VMle proxy attache le vrai secret uniquement sur le fil, uniquement pour un appel que vous avez autorisé, puis le retiresupprimez la VM et l'évasion, l'écrasement et la persistance partent avec elle
DuneSlide rejoué contre Bromure Agentic Coding. Le résultat MCP ou l'extrait web non fiable atteint d'abord le proxy côté hôte, où PromptGuard le score avant que le modèle ne le lise. Si l'injection passe cette vérification, l'évasion via run_terminal_cmd et le lien symbolique se déclenche tout de même, mais elle écrase des fichiers à l'intérieur de la VM jetable, pas sur le Mac. Le shell évadé chasse les tokens et trouve des stubs de substitution, parce que les vrais identifiants vivent sur l'hôte et ne franchissent la frontière vers l'invité qu'au niveau du fil, pour un appel que l'agent a fait pour un vrai travail, avec les opérations modifiant l'état suspendues pour confirmation. La garantie vient de la frontière de la VM et de la substitution de token ; PromptGuard est le fil-piège qui attrape l'injection plus tôt.

L'évasion atterrit dans l'invité.

Les deux CVE se déclenchent toujours sous Bromure. L'écrasement frappe des fichiers à l'intérieur d'une VM jetable dotée de son propre noyau, et l'hyperviseur ne donne à l'invité aucun appel système qui atteint l'hôte. Vous reconstruisez la VM et les dégâts partent avec elle.

Le token qu'elle voulait n'a jamais été là.

Le but de DuneSlide est l'accès cloud et SaaS du développeur. Ces secrets se trouvent sur l'hôte, et la VM ne porte que des stubs qui ne signifient rien sur l'internet. Le shell évadé grep les tokens et ne lit que des substituts, si bien que l'étape de récompense échoue.

PromptGuard lit le fil en premier.

La garantie ci-dessus tient sans aucun classifieur : la frontière de la VM contient l'évasion et la substitution de token affame la récompense, quoi que fasse le modèle. Bromure ajoute une couche de plus au même proxy, visant le vecteur exact qu'utilise DuneSlide. L'injection voyage dans du contenu que l'agent ingère, un résultat d'outil MCP ou un extrait de recherche web, et ce contenu traverse le proxy hôte avant que le modèle ne le lise. Si activé, PromptGuard le score à cet endroit. L'étape une est le Llama Prompt Guard 2 de Meta, qui surveille la sortie d'outil et les récupérations web à la recherche de texte qui s'adresse au modèle comme une instruction. Les fichiers de règles qu'un agent traite comme des consignes permanentes, CLAUDE.md et ses semblables, reçoivent à la place un classifieur ModernBERT affiné, parce qu'un fichier censé n'être que des instructions a besoin d'un modèle qui score la nocivité plutôt que l'injection.

Selon le profil, Bromure journalise le déclenchement, vous le montre pour une décision, ou le bloque avant que le modèle ne voie la portion empoisonnée. Le placement est tout l'enjeu, et c'est le même argument que les couches en dessous : un agent qui a déjà avalé l'injection ne peut pas être digne de confiance pour la signaler, donc la vérification s'exécute de l'autre côté de la frontière, là où la persuasion de l'agent n'atteint pas. Nous avons décrit le pipeline complet dans comment Bromure détecte les prompts malveillants, et observé la même classe d'attaque s'inviter dans la sortie d'une commande dans l'instruction qui n'était pas de moi.

DuneSlide est corrigé dans Cursor 3.0, et se mettre à jour est le bon geste aujourd'hui. Le schéma qui le sous-tend n'est pas corrigé, parce que ce n'est pas une faille unique. Tout agent de codage qui fait tourner son propre confinement dans son propre processus est à une phrase convaincante de l'édition de ce confinement. Le geste qui survit à la prochaine CVE portant un nom différent, c'est de garder le garde, les identifiants et la piste d'audit de l'autre côté d'une ligne que l'agent ne peut pas écrire. Bromure Agentic Coding trace cette ligne à l'hyperviseur. Il est gratuit, open source, et livré aujourd'hui.