# Un agent s’est laissé convaincre d’envoyer 150 000 $ en morse

> Ni faille ni clé volée : juste un message que le modèle a accepté de suivre. L’injection de prompt ne se corrige pas : que peut exprimer un modèle persuadé ?

- Source: https://defiloops.com/fr/blog/talked-into-sending-150000
- Published: 2026-09-01
- Category: Security
- Tags: security, prompt-injection, agents, permissions
- Author: DeFiLoops

---
En mai 2026, quelqu’un a [sorti 150 000 $ d’un portefeuille intégré à une IA](https://www.giskard.ai/knowledge/how-grok-got-prompt-injected-an-x-user-drained-150-000-from-an-ai-wallet) sans trouver le moindre bug.

Il a envoyé un NFT d’adhésion au portefeuille, ce qui l’a discrètement fait passer à un palier de permissions supérieur. Puis il a
publié une réponse sur X contenant une instruction dissimulée en morse. L’agent — Grok, branché sur un bot de trading — a décodé le
morse, lu l’instruction, jugé qu’il s’agissait d’une commande légitime, et autorisé le transfert.

Aucune faille. Aucune clé volée. Aucun serveur compromis. On a simplement demandé gentiment au modèle, dans un format que personne
n’avait pensé à traiter avec méfiance.

## Deux défaillances, et une seule dont on parle

Les deux ont un nom : [OWASP LLM01:2025 et LLM06:2025](https://genai.owasp.org/llm-top-10/) — la première et la sixième
entrées de la liste standard des défaillances des applications à modèle de langage.

<Compare left="Injection de prompt" right="Agentivité excessive" verdict>
  <Fragment slot="left">
    Le modèle n’a pas su distinguer une instruction *de son mandant* d’une instruction *dans son entrée*. Tout le monde travaille
    là-dessus. Personne ne l’a résolu.
  </Fragment>
  <Fragment slot="right">
    Une fois convaincu, le modèle a pu exprimer « envoie tout à cette adresse ».

    Ce n’est pas du tout un problème de modèle. C’est une question sur ce que le système autour de lui permet d’écrire.
  </Fragment>
</Compare>

La première défaillance est celle qui fait les gros titres. La seconde est celle qui a décidé du montant.

<Callout type="warn" title="Traitez l’injection comme acquise">
  Le contenu encodé rend cela concret : tout texte passant par une couche de traduction ou de décodage devrait être traité comme
  potentiellement injecté. Le morse a marché. Le base64 marchera aussi, une image aussi, une langue dans laquelle les garde-fous n’ont
  pas été évalués aussi. On ne peut pas énumérer les encodages.
</Callout>

Si l’injection va se produire, la question de conception n’est pas *comment empêcher qu’on abuse le modèle*. C’est **que peut réellement
faire un modèle abusé**.

## La réponse du secteur, et là où elle s’arrête

Lisez une douzaine de pages d’éditeurs sur la sécurité des portefeuilles agentiques et vous obtenez la même liste : moindre privilège,
clés de session bornées, plafonds par transaction et par jour, une liste blanche de destinataires, confirmation humaine pour tout ce
qui est irréversible, clés isolées du processus de raisonnement.

Tout cela est bon. Une partie ne se fait pas : **[45,6 % des équipes](https://www.gravitee.io/blog/state-of-ai-agent-security-2026-report-when-adoption-outpaces-control) partagent encore une seule clé d’API entre leurs agents**, ce qui
rend presque impossible de tracer ou d’arrêter un agent qui a mal tourné. Les totaux publiés sur les brèches d’agents méritent la prudence : le chiffre phare du
premier trimestre 2026 est dominé par un seul incident que les sources primaires imputent à
des ordinateurs de direction compromis, et non à quoi que ce soit de propre aux agents. Le
mode de défaillance bien étayé est plus étroit et plus utile : les attaques sur la mémoire
des agents et sur les protocoles qui les relient à leurs outils.

Mais le problème de fond, c’est que toute la liste partage une hypothèse :

<Quote>
  Les périmètres de permission doivent être définis précisément, mais les définir précisément est difficile, parce que les agents
  agissent sur une intention exprimée en langage et que le langage est ambigu.
</Quote>

Cette phrase, ou une quasi-identique, apparaît dans tout le secteur. Elle est traitée comme un problème difficile à gérer avec des
périmètres toujours plus serrés.

C’est un problème difficile. Il n’est inévitable que si le modèle compose des appels.

## Nous avons plutôt retiré le champ

L’agent, ici, n’écrit pas d’instructions. Il remplit un formulaire fixe de cases étiquetées, issues d’un catalogue fermé d’opérations.

<Spec title="Ce que le formulaire peut porter" rows={[
  ['montant', 'Une quantité, dans l’échelle propre de l’actif'],
  ['actif', 'Un symbole de la liste du réseau — jamais une adresse'],
  ['réseau', 'L’un des réseaux pris en charge'],
  ['rôle', 'Une destination nommée, par exemple « le compte du propriétaire » — jamais une adresse brute'],
  ['marché', 'Un nom de marché curé, jamais un identifiant'],
  ['points de base, échéance, prix, tick', 'Des types numériques bornés'],
]} />

<Callout type="danger" title="Il n’y a délibérément ni type « octets bruts » ni type « n’importe quoi »">
  L’un ou l’autre permettrait à un appelant de faire passer une instruction par un champ, et cela détruirait toute la propriété. Pas de
  case pour une adresse de destination, pas de case pour une charge utile.
</Callout>

Alors lancez l’attaque en morse contre ceci. Le modèle est convaincu — admettez-le complètement. Il veut maintenant envoyer vos fonds à
un attaquant.

Il ne peut pas l’écrire. Les destinations sont des **rôles**, résolus depuis votre compte au moment où l’étape s’exécute. Il n’existe
aucun champ où l’adresse d’un attaquant pourrait aller, donc rien n’a besoin de détecter la tentative.

<Steps>
  <Step title="Une opération absente de la liste ne peut pas être nommée">
    Un plan nommant quelque chose hors du catalogue est refusé à l’écriture, pas tenté puis échoué à mi-parcours.
  </Step>
  <Step title="Tout ce qui est produit vous revient">
    La destination est un rôle résolu depuis votre compte, jamais une valeur que le plan fournit.
  </Step>
  <Step title="Les plafonds sont fixés dans votre compte">
    Par actif, par période. Rien de notre côté ne peut les relever.
  </Step>
  <Step title="L’agent est un contrat, pas une clé">
    Une clé peut être volée et utilisée par celui qui la détient. Un contrat ne peut qu’être nommé ou non — et la nomination est à sens
    unique, si bien qu’un compte ne peut jamais être redirigé vers un autre agent.
  </Step>
</Steps>

## Là où cela cesse d’être confortable

Tout ce qui précède est réel et rien de tout cela ne nous rend sûrs en général. Trois choses à mettre en balance :

<Callout type="warn" title="La garde est une liste d’interdictions">
  Ce qui empêche l’agent de mal se comporter interdit des actions précises plutôt que de n’autoriser que les connues-bonnes. Cela bloque
  totalement une prise de contrôle : l’agent ne peut jamais devenir propriétaire ni céder votre compte à quelqu’un d’autre. Cela ne bloque
  pas toutes les façons dont la valeur pourrait bouger via une action que personne n’a pensé à interdire.

  **Nous avons prouvé quatre attaques de ce type contre nous-mêmes**, sur une copie du réseau Base réel, dans la même configuration qu’en
  production.
</Callout>

Elles sont atteignables dans deux situations : un mode permissif dans lequel nous ne tournons pas par défaut, et partout où quelqu’un détient
la clé keeper directement et ne passe donc jamais par notre service de signature. En fonctionnement normal, ce service ne produit pas la forme
d’instruction qui les atteint. C’est une protection réelle, et ce n’est pas la même chose que le trou soit bouché.

Deuxièmement : **il n’y a aucun audit externe.** Chaque assurance que nous donnons est notre propre test.

Troisièmement : le service qui détient la clé keeper refuse de démarrer en production, délibérément, parce qu’il garde actuellement cette clé
en mémoire.

## Ce qu’il faut vraiment retenir de l’histoire du morse

Pas qu’un produit ait été négligent. L’erreur précise — un transfert de NFT qui élève discrètement un palier de permissions — est inhabituelle,
mais la forme ne l’est pas.

La forme, c’est : **un système où être convaincu et pouvoir agir sont le même événement.**

<Quote cite="La seule défense structurelle que nous connaissions">
  L’injection, on ne peut pas l’empêcher. L’expressivité, on peut la retirer.
</Quote>

Si vous évaluez un agent qui touche à de l’argent, c’est la question qui mérite d’être posée, et on peut y répondre sans se fier à la page de
sécurité de qui que ce soit. Demandez ce que l’agent est capable d’écrire. Si la réponse inclut une adresse, tous les autres contrôles sont un
filtre entre un modèle persuadable et vos fonds — et les filtres sont évalués contre les attaques auxquelles quelqu’un a déjà pensé.

Le nôtre n’inclut pas d’adresse. Nous préférerions tout de même que vous supposiez que quelque chose nous a échappé, car à quatre reprises, c’est
arrivé.