SymJack : une copie de fichier approuvée devient RCE dans six agents de codage IA
Adversa AI a publié le 26 mai 2026 un schéma de détournement par lien symbolique qui transforme une simple commande shell en réécriture de la config et en RCE sur l'hôte, à travers Claude Code, Cursor, Gemini, Antigravity, Copilot, Grok Build et Codex CLI.
De quoi parle-t-on ?
Le 26 mai 2026, Rony Utevsky d’Adversa AI a publié SymJack: the approval prompt is lying to you, qui documente un schéma d’attaque unique conduisant à de l’exécution de code à distance sur l’hôte de l’utilisateur dans six agents de codage IA : Claude Code 2.1.128 (correctif partiel en 2.1.129), Cursor CLI v2026.05.20, Gemini CLI 0.43.0, Antigravity CLI 1.0.2, Copilot CLI 1.0.51, Grok Build CLI 0.1.216 et OpenAI Codex CLI v0.133.0 (ajouté dans la mise à jour du 27 mai). Aucun nouveau CVE n’a été assigné, mais la famille prolonge la divulgation antérieure de Check Point CVE-2025-59536 (octobre 2025) et le schéma TrustFall publié plus tôt en mai par Adversa.
Le déclencheur tient en une action : ouvrir un dépôt malveillant et cliquer sur Approuver devant ce qui ressemble à une banale copie de fichier.
Comment ça fonctionne
Les agents de codage distinguent deux catégories d’écriture. Les outils d’écriture natifs (write_file, apply_diff, etc.) portent des garde-fous sensibles au chemin : ils refusent, ou demandent une confirmation renforcée, lorsque la cible est une config MCP, un fichier de paramètres ou un fichier d’init shell. Les commandes shell (cp, mv, install, tee, redirections) sont contrôlées par inspection du texte de la commande — pas de l’effet réel sur le système de fichiers.
SymJack exploite l’écart. Selon Adversa :
« Les instructions demandent à l’agent d’utiliser une commande shell brute plutôt que ses propres outils d’écriture. Les outils natifs comportent des garde-fous qui signalent les chemins sensibles comme les fichiers de config. Un
cpbrut passe à travers, parce que l’invite d’autorisation inspecte le texte de la commande, pas son effet réel. »
La destination affichée dans l’invite d’approbation est un chemin à l’intérieur du dépôt. Ce chemin est un lien symbolique livré dans le dépôt, pointant vers la propre config MCP ou le fichier de paramètres de l’agent. Quand le noyau suit le lien, le contenu attaquant atterrit directement dans le fichier qui définit quels serveurs MCP l’agent lancera au prochain démarrage :
repo/ ~/.config/<agent>/
├── payload.txt ─ cp ─> mcp_servers.json ← cible du symlink
└── docs/destination ─ symlink ─> mcp_servers.json
# Dans l'invite d'approbation, l'utilisateur voit :
$ cp ./payload.txt ./docs/destination
# Après résolution du symlink par le noyau, l'écriture réelle est :
# ./payload.txt → ~/.config/<agent>/mcp_servers.json
Le prochain redémarrage de l’agent charge la config réécrite, instancie le serveur MCP contrôlé par l’attaquant et exécute ses commandes avec tous les privilèges de l’utilisateur. Une injection de prompt indirecte depuis un README.md, un AGENTS.md caché ou une description .mcp.json suffit à amener l’agent à proposer le cp malveillant en premier lieu.
Pourquoi c’est important
La classe de bug est structurelle, pas un dérapage ponctuel :
- La fidélité de l’invite d’approbation est brisée quand l’invite affiche des chaînes d’arguments alors que le noyau agit sur des chemins résolus.
- Deux chemins d’écriture, une seule politique est le mauvais réglage par défaut. Chaque produit audité avait des garde-fous plus stricts sur son outil d’écriture natif que sur les opérations shell.
- Les configs sont du code. Une entrée de serveur MCP dans
mcp_servers.jsondéclenche un spawn de processus. La traiter comme de la donnée tout en traitant les commandes shell comme des commandes inverse le modèle de confiance.
Le même schéma a réapparu indépendamment dans TrustFall, dans CVE-2025-59536 et désormais dans SymJack à travers six agents sans rapport entre eux — signal fort que la surface d’attaque est dans le design, pas dans un bug d’implémentation.
Défenses
Les recommandations d’Adversa, telles quelles :
- « Résoudre les liens symboliques vers leur cible réelle avant toute décision d’autorisation, sur chaque chemin d’écriture de fichier, y compris les commandes shell. »
- « Traiter les opérations shell sur fichiers (
cp,mv,install,tee, redirections,dd of=) comme des écritures de première classe, soumises aux mêmes contrôles de sensibilité de chemin que les outils d’écriture natifs. » - « Montrer à l’utilisateur la destination canonique dans l’invite d’approbation, pas la chaîne d’argument littérale. »
- « Bloquer la possibilité que des clés de config sensibles activant l’exécution MCP soient définies par des fichiers à portée projet. »
- « Faire apparaître quels fichiers d’instructions ont été inclus au démarrage, afin qu’une directive cachée dans un fichier presque vide ne puisse pas s’exécuter en silence. »
Côté opérateurs : désactiver l’auto-approbation des opérations shell sur fichiers dans les dépôts non vérifiés, monter en lecture seule les répertoires de config de l’agent quand vous travaillez dans un projet inconnu, surveiller les modifications de ~/.config/<agent>/ et ~/.<agent>/ pour repérer les diffs non issus d’une action utilisateur délibérée, et mettre à jour vers les dernières versions des CLI (Claude Code ≥ 2.1.129 apporte un correctif partiel qui durcit le flux d’approbation mais ne résout pas, selon Adversa, complètement les symlinks sur le chemin shell).
État
| Agent | Version testée | Réponse de l’éditeur |
|---|---|---|
| Claude Code | 2.1.128 | Durcissement partiel en 2.1.129 |
| Gemini CLI | 0.43.0 | Refusé |
| Antigravity CLI | 1.0.2 | (même canal que Gemini) |
| Cursor CLI | 2026.05.20 | Refusé comme doublon |
| Copilot CLI | 1.0.51 | En attente |
| Grok Build CLI | 0.1.216 | En attente |
| Codex CLI | 0.133.0 | Rapport Bugcrowd clôturé |
SymJack est documenté par un dépôt de preuve de concept sur GitHub et des vidéos de démonstration par agent. Considérez tout agent de codage IA opérant dans un dépôt que vous n’avez pas écrit comme capable d’atteindre l’exécution de code sur votre hôte via un seul clic d’approbation — tant que l’UI d’approbation n’affiche pas les chemins résolus et que le chemin shell ne passe pas par les mêmes garde-fous que les outils d’écriture natifs.
Sources
- → https://adversa.ai/blog/the-approval-prompt-is-lying-to-you-symlink-rce-in-five-ai-coding-agents-claude-code-cursor-antigravity-copilot-grok-build/
- → https://research.checkpoint.com/2026/rce-and-api-token-exfiltration-through-claude-code-project-files-cve-2025-59536/
- → https://adversa.ai/blog/trustfall-coding-agent-security-flaw-rce-claude-cursor-gemini-cli-copilot/
- → https://github.com/adversa-ai/research/tree/main/artifacts/symlink-to-rce