Un inconnu a pointé le module
Un Gnosis Safe a perdu 7,8 millions de dollars en ETH restaké — non parce que le Safe était défaillant, mais parce qu'un module activé a laissé un keeper quelconque le pointer vers la pool de l'attaquant. La classe est ancienne. La leçon tient à l'endroit d'où vous laissez venir une destination.
- Ce qui s’est réellement passé
- Le bug est dans l’origine de la destination
- Le rebondissement, puisqu’il est bon
- Cela peut-il arriver à un compte DeFiLoops ?
- Le plan de l’attaquant, étape par étape
- Ce que nous n’affirmons pas
- La partie qui a changé notre propre confiance
- Comment évaluer toute affirmation de ce genre
Le 15 septembre 2026, un utilisateur d’Ethereum a perdu environ 7,8 millions de dollars en ETH restaké depuis un portefeuille multisignature. Il y a un rebondissement mémorable —un bot de front-running a pris l’argent avant l’attaquant lui-même— mais le rebondissement n’est pas la leçon. La leçon, ce sont les quatre secondes d’avant, quand le portefeuille a fait exactement ce qu’on lui a ordonné, ordonné par quelqu’un qui n’aurait dû pouvoir lui ordonner quoi que ce soit.
Voici la forme de l’attaque, car c’est l’une des façons les plus courantes de vider un compte intelligent et la partie défaillante paraît toujours correcte.
Ce qui s’est réellement passé
La victime détenait environ 2 900 rsETH —un jeton de restaking liquide— dans un Gnosis Safe, sous sa forme enveloppée par Aave. L’attaquant n’a jamais eu de clé.
À la place, il a utilisé un appel public de keeper pour pointer un module de liquidité Uniswap V4 —un module que le compte avait activé— vers une pool que l’attaquant venait de créer. Cette pool portait un hook malveillant. Le hook a déballé la position en rsETH librement transférable, et le module, agissant avec l’autorité du Safe, l’a déplacé.
Le bug est dans l’origine de la destination
Retirez le restaking et les hooks, il reste une seule clause. Un module de confiance a reçu une destination —quelle pool, quel contrat— de son appelant, et il a agi sur cette destination depuis l’intérieur de son propre contexte privilégié. La validation qu’il faisait ne suffisait pas, car l’attaquant pouvait choisir la seule chose qui décidait où allait l’argent.
La pool par laquelle router. Une adresse de contrat, choisie au moment de l’appel, par un keeper public que n’importe qui peut invoquer.
Rien qui décide d’une destination. Le lieu est nommé depuis une liste que le propriétaire a installée ; le destinataire est le compte, toujours ; le module compose l’appel.
Un module qui prend sa destination de son appelant est un module qui fait confiance à l’appelant pour le pointer. Sur une voie de keeper public, l’appelant est le public. L’attaquant n’a pas forcé l’entrée. On lui a mis le volant entre les mains en lui demandant d’être poli.
Le rebondissement, puisqu’il est bon
La transaction de l’exploit est entrée dans le mempool public —la salle d’attente où les transactions non confirmées sont à découvert. Un bot généralisé de front-running nommé Yoink a vu le drainage en attente, l’a copié avec des frais plus élevés et a exécuté en premier dans le même bloc. L’attaquant initial n’a rien eu.
Cela peut-il arriver à un compte DeFiLoops ?
C’est la question que se pose vraiment un lecteur à notre place, alors voici la réponse honnête : le geste précis —pointer un module de confiance vers le contrat d’un attaquant— ne peut pas s’exprimer contre un compte DeFiLoops, et non par chance mais par conception. Non parce que nos vérifications sont plus soigneuses. Parce qu’on ne remet jamais à l’agent de destination à pointer.
- Choisir la pool / le contrat par lequel router
- Aucun champ de ce genre. L'agent fournit des paramètres typés ; l'adaptateur compose l'appel et choisit la destination.
- Nommer un lieu par adresse
- Refusé. Les lieux sont nommés depuis l'ensemble que le propriétaire a installé, jamais comme une adresse dans l'instruction.
- Rediriger le paiement vers soi
- Le destinataire est forcé au compte, lu depuis le compte — jamais pris de l'instruction.
- Prouver que vous visiez ce compte
- Le propriétaire est lu depuis le compte. Une signature valide de l'agent ne prouve pas que le bon compte, ni la bonne destination, étaient visés.
La raison plus profonde se situe un niveau au-dessus. Un compte DeFiLoops en production ne donne à l’agent aucune voie d’appel directe. Le Safe vidé avait un module qui pouvait exécuter un appel choisi par l’appelant. Notre agent ne peut pas composer d’appel. Il fournit un montant, un lieu nommé depuis une liste, une plage — et un adaptateur inscrit sur la liste blanche construit la transaction. Il n’y a pas de contrat fourni, car l’agent n’en fournit jamais.
Le plan de l’attaquant, étape par étape
Supposez l’attaquant réaliste le plus fort, hormis le vol de votre clé de propriétaire : il détient la clé de l’agent, celle qui signe les instructions quotidiennes du compte. Voici ce qu’il tenterait, et où chaque étape s’arrête.
- Pointer un module vers une pool que vous contrôlez
Aucun module ne prend de pool de son appelant. Le trading passe par des adaptateurs qui lisent le lieu depuis l’ensemble installé par le propriétaire. Une pool créée par l’attaquant n’y figure pas, et une adresse dans l’instruction est refusée comme appel arbitraire.
- Se rabattre sur un appel direct et choisir sa propre destination
En production, il n’y a aucune voie d’appel directe sur laquelle se rabattre. Elle n’est pas installée. Le geste n’a nulle part où s’écrire.
- Router par un adaptateur légitime et rediriger les fonds
Le destinataire est forcé au compte, le propriétaire est lu depuis le compte, le lieu vient de l’ensemble du propriétaire et la dépense est plafonnée par période. Chaque destination est fixée par l’adaptateur, pas par l’instruction.
- Installer son propre module, ou changer la racine du compte
Ces sélecteurs sont refusés. L’agent ne peut jamais installer le genre de module redirigeable qui a vidé le Safe, devenir le propriétaire ou céder le compte.
- Pendant ce temps, le propriétaire révoque l'agent
Une transaction, sans la coopération de personne, et toute instruction future de cette clé est refusée avant même que sa destination soit inspectée. La clé volée meurt dès que le propriétaire agit.
Une clé d’agent volée, contre un compte en production, ne peut rien pointer vers un attaquant ni prendre le contrôle. C’est toute l’affirmation de sécurité, et elle tient contre cette attaque précise.
Ce que nous n’affirmons pas
Un article de sécurité qui s’arrête là vend quelque chose. La limite honnête a trois bords, et aucun n’est cette attaque.
La partie qui a changé notre propre confiance
Nous voulions prouver que le guard bloque ceci. Écrire cette preuve a révélé que les tests que nous avions déjà ne le prouvaient pas — ils révertaient une couche trop tôt, dans la plomberie du compte, et passaient parce que le framework de test appariait mal le revert. La protection était réelle. La preuve, elle, était du théâtre.
Un test de sécurité qui ne peut pas échouer quand on casse ce qu’il protège n’est pas un test faible. C’est une décoration, et il est plus dangereux qu’aucun test, car il se lit comme une couverture.
Nous avons donc reconstruit la preuve contre le guard directement, en affirmant la raison exacte pour laquelle chaque appel est refusé, puis en cassant chaque contrôle à dessein pour voir le test correspondant échouer. Retirer la ligne d’auto-référence fait échouer son test. Neutraliser la voie de révocation en fait échouer une autre. C’est la différence entre croire qu’une limite tient et le savoir.
Comment évaluer toute affirmation de ce genre
Vous n’avez pas à faire confiance à cette page. La question qui sépare une vraie limite d’un filtre est toujours la même : que peut écrire l’agent, ou un keeper de passage ?
Si la réponse inclut une destination —une pool, un contrat, une adresse que l’appelant choisit— alors chaque garde-fou autour est une vérification placée entre la cible choisie par un inconnu et votre argent, et les vérifications se jugent contre les attaques que quelqu’un a déjà imaginées. Le drainage de septembre, c’est le coût d’une destination choisie par l’appelant.
Si la réponse est des paramètres typés et rien d’autre, l’attaque de cet article n’a nulle part où atterrir, car ce qu’elle exploite —une cible que vous pouvez nommer— n’a jamais été remis.
Sources : rapports de surveillance de PeckShieldAlert et Blockaid (15 septembre 2026), repris par PANews, Odaily, Foresight News et BlockBeats ; transactions on-chain via Etherscan. Les chiffres et le mécanisme sont ceux rapportés à l’époque et peuvent être révisés à mesure que l’analyse avance.