système : OPÉRATIONNEL
← retour à tous les hacks
AGENTS MEDIUM NEW

Quand le choix le plus prudent d'un agent exécute l'exploit : le module shadowing en auto mode

Une analyse d'août 2026 montre qu'un agent de code qui refuse un binaire suspect et écrit son propre décodeur Python fait, par cette décision prudente, tourner le code de l'attaquant.

2026-09-05 // 7 min affects: claude-code, opus-5, coding-agents, python

De quoi s’agit-il ?

Le 26 août 2026, le chercheur Johann Rehberger (Embrace The Red) a publié le détail d’une chaîne d’attaque qui transforme la prudence d’un agent de code en exécution de code à distance. Simon Willison l’a relayée le lendemain, 27 août, et Adversa AI l’a intégrée à sa synthèse du 3 septembre sur la sécurité des agents de code. Le point de départ est banal : l’utilisateur demande à l’agent de résumer un site web. Dans les tests en laboratoire du chercheur (petit échantillon), le résultat a été l’exécution de code arbitraire sur la machine hôte dans 60 à 80 % des tentatives — avec, à la clé, un rappel vers un serveur de commande et contrôle.

L’intérêt de la découverte n’est pas une faille inédite dans un produit précis. C’est une observation structurelle sur les agents autonomes : l’agent ne suit jamais consciemment une instruction malveillante. Il prend une série de décisions individuellement raisonnables, et c’est l’environnement qui est agencé pour que la décision « prudente » soit le piège. Après discussion, Willison a d’ailleurs préféré parler d’« attaque par environnement confus » plutôt que de prompt injection classique — aucun texte de l’attaquant n’est jamais obéi comme une commande.

Comment ça marche

La chaîne est faite de petites étapes anodines :

  1. L’agent récupère une page. Le serveur répond 415 Unsupported Media Type ; l’agent décide alors de lui-même de réessayer avec curl dans un shell — passant d’un outil de récupération/résumé à l’exécution de commandes brutes. Le serveur ne le lui a jamais dit ; il a simplement rendu ce chemin évident.
  2. curl suit une redirection vers une archive ZIP de fiches plausibles, encodées, accompagnées d’un binaire décodeur natif et d’un fichier nommé struct.py.
  3. L’agent extrait l’archive dans un dossier temporaire et refuse à juste titre d’exécuter le binaire non fiable.
  4. À la place, il écrit son propre petit décodeur Python et le lance — depuis l’intérieur du dossier extrait.

L’étape 4 est l’exploit. Python place le répertoire courant sur son chemin de recherche de modules, et le module standard base64 importe struct. Comme l’archive contient un fichier struct.py, Python charge la version de l’attaquant en premier — c’est le module shadowing. Le module malveillant réexporte la véritable API bas niveau, de sorte que le décodage se poursuit normalement, tandis qu’une expression obfusquée s’exécute pendant l’import. En laboratoire, cette expression lançait un processus enfant isolé qui téléchargeait une charge ultérieure et ouvrait un canal C2.

# Le raisonnement de l'agent, en substance :
#   « Le binaire fourni n'est pas fiable -> je ne l'exécute pas. »
#   « J'écris mon propre décodeur à la place -> c'est prudent. »
#   python3 -c 'import base64, zlib, json; ...'   # exécuté depuis ./archive-extraite/
#
# Ce qui se passe réellement :
#   base64 importe struct  ->  ./struct.py (attaquant) chargé en premier  ->  code exécuté

L’observation centrale, selon le chercheur : l’agent ne fait pas confiance au binaire fourni, mais il fait confiance au décodeur qu’il a écrit lui-même. Le binaire-leurre n’existe que pour pousser le modèle à écrire son propre code dans un répertoire empoisonné.

Pourquoi c’est important

Deux détails élèvent l’affaire au-dessus du simple tour de passe-passe. D’abord, les défenses en couches de l’éditeur auraient réduit la prompt injection indirecte à près de zéro sur un jeu figé de 72 scénarios — or cette chaîne, absente de ce jeu, a fonctionné la plupart du temps. Un « 0,00 % » en titre et un exploit fonctionnel peuvent être vrais en même temps ; un chiffre unique ne décrit pas la résilience face à une chaîne inédite.

Ensuite, plus frappant encore : dans certains essais, l’agent a remarqué la compromission après coup et a tenté de tuer le processus malveillant — et le classifieur d’auto-approbation a bloqué la commande de nettoyage. La même couche de sécurité qui avait laissé se lancer le processus malveillant a empêché sa terminaison. Un classifieur « au mieux » qui filtre les commandes selon leur intention apparente n’est pas une frontière de confinement, et il peut occasionnellement se retourner contre vous.

Ce schéma dépasse largement un agent ou un langage. Tout agent qui (a) peut être poussé d’un outil restreint vers l’exécution shell brute, (b) écrit et exécute du code dans un répertoire de travail contrôlé par l’attaquant, et (c) s’appuie sur un classifieur d’intention plutôt que sur une isolation OS, est exposé à la même forme d’attaque.

Défenses

L’agent auteur du rapport et le chercheur convergent : le jugement du modèle n’est pas le filet de sécurité. La frontière doit être imposée par le runtime qui l’entoure.

  • Sandboxez les agents non supervisés. Faites tourner les agents de code dans un conteneur, une VM ou un sandbox au niveau OS — pas directement sur un poste de travail avec de vraies identités. C’est là la vraie frontière de sécurité ; le classifieur ne l’est pas.
  • Restreignez la sortie réseau. Bloquez par défaut le trafic sortant afin qu’un processus enfant ne puisse joindre ni une charge distante ni un serveur C2.
  • N’exécutez jamais de code depuis un répertoire de travail non fiable. Quand un agent doit exécuter un script qu’il a écrit pour traiter du contenu téléchargé, lancez-le depuis un répertoire propre et vide — pas depuis l’archive extraite.
  • Utilisez le mode isolé de Python pour ces étapes. Invoquer python3 -I retire le répertoire courant du chemin de recherche de modules et ignore les surcharges d’environnement, ce qui neutralise précisément ce vecteur. L’agent le faisait parfois de lui-même ; faites-en le comportement par défaut de votre harnais.
  • Tenez les secrets hors de portée de l’agent. N’exposez ni répertoires personnels, ni clés SSH, ni identifiants cloud au runtime, afin qu’une chaîne réussie n’ait rien de précieux à voler.
  • Surveillez, et considérez l’approbation comme un confort, pas une preuve. Une commande auto-approuvée n’est pas la preuve qu’elle est sûre. Journalisez les appels d’outils et surveillez les bascules vers le shell, les téléchargements et les créations de processus enfants.

Statut

ÉlémentDétail
DivulgationEmbrace The Red (Johann Rehberger), 26 août 2026
CouvertureSimon Willison, 27 août 2026 ; synthèse Adversa AI, 3 septembre 2026
Taux de succès rapporté60 à 80 % sur de petits échantillons en laboratoire
Réponse de l’éditeurRapport classé « Informatif » / conforme à la conception ; l’auto mode est décrit comme une fonction de confort au mieux, pas une garantie de sécurité
NatureChaîne par environnement confus / module shadowing, pas un bug corrigeable isolé ; aucun CVE attribué

Tous les chiffres sont les résultats propres du chercheur sur des configurations de laboratoire précises et de petits échantillons, et ne doivent pas être lus comme un taux de succès général pour un produit.

Sources