原文标题:《Contourner la couche zéro : pourquoi la sécurité isolée n'est pas une sécurité》
Auteur : Krzysztof Urbański, membre de l'équipe L2BEAT
Compilé par : Babywhale, Foresight News
L2BEAT a investi des efforts considérables depuis sa création pour analyser et comprendre les risques associés aux protocoles de couche 2. Nous agissons toujours dans le meilleur intérêt de nos utilisateurs et de notre écosystème, et faisons de notre mieux pour être un superviseur impartial et indépendant, sans laisser nos préférences personnelles pour les projets ou les équipes associées influencer les faits. C’est pourquoi, même si nous respectons le temps et les efforts que l’équipe de projet consacre au projet, nous pouvons « tirer la sonnette d’alarme » ou souligner nos inquiétudes quant aux risques potentiels de certains protocoles. Avoir des discussions précoces sur la sécurité permet à l’ensemble de l’écosystème d’être mieux préparé aux risques potentiels et de réagir plus tôt à tout comportement suspect.
Aujourd'hui, nous aimerions discuter du modèle de sécurité partagé pour les applications inter-chaînes. Il existe actuellement deux modèles de sécurité : la sécurité partagée et la sécurité des applications indépendantes. La sécurité partagée est comme tous les Rollups. La sécurité des applications autonomes est principalement utilisée par les projets « omnichain », qui utilisent principalement LayerZero.
Sécurité partagée vs sécurité indépendante
La sécurité partagée fait référence à un jeton ou une application spécifique exécuté sur une infrastructure donnée, et plutôt que de choisir librement un modèle de sécurité, ils doivent adhérer à toutes les exigences de sécurité imposées par l'infrastructure. Par exemple, les rollups optimistes imposent généralement une fenêtre finale de 7 jours : une application exécutée sur de tels rollups ne peut pas simplement ignorer ou raccourcir cette période. Même si cela peut sembler un obstacle, il y a une raison à cela. Cette période offre aux utilisateurs l'assurance de sécurité que, quelle que soit la politique de sécurité interne de l'application, qui doit être respectée, l'application ne peut que renforcer la sécurité des Rollups, et non l'affaiblir.
Une sécurité indépendante signifie que chaque application est responsable de la définition de sa sécurité et n'est en aucun cas limitée par l'infrastructure. Cela peut sembler une bonne idée au début, après tout, le développeur de l’application connaît mieux que quiconque les mesures de sécurité dont l’application peut avoir besoin. Mais en même temps, cela transfère la responsabilité de l’évaluation des risques associés à chaque politique de sécurité des applications vers l’utilisateur final. De plus, si les développeurs d’applications sont libres de choisir leurs politiques de sécurité, ils peuvent également les modifier à tout moment. Par conséquent, il ne suffit pas d'évaluer le risque une fois pour chaque application ; il faut l'évaluer à chaque fois que les politiques d'une application changent.
Problèmes
Nous pensons qu'un modèle de sécurité indépendant dans lequel chaque application est libre de définir sa politique de sécurité crée de sérieux problèmes de sécurité. Premièrement, cela augmente le risque pour les utilisateurs finaux, car ils doivent vérifier le risque pour chaque application qu'ils ont l'intention d'utiliser.
La sécurité autonome augmente également les risques pour les applications qui utilisent ce modèle, par exemple en ajoutant des risques supplémentaires concernant les changements de politique de sécurité - si un attaquant devait modifier le modèle de sécurité de l'application, il pourrait tout aussi bien la désactiver, se retrouvant ainsi à court d'argent ou en risquant de toute façon. Attaquer d’une autre manière. Il n'y a pas de couches de sécurité supplémentaires au-dessus de l'application pour empêcher les attaques.
De plus, étant donné que les politiques de sécurité peuvent changer à tout moment et à la volée, il est presque impossible de surveiller les applications en temps réel et d'informer les utilisateurs des risques.
Nous avons trouvé cela similaire à l’évolutivité des contrats intelligents, dont nous avions mis en garde sur L2BEAT. Nous informons les utilisateurs sur les ponts Rollup et cross-chain qui ont des mécanismes d'évolutivité dans leurs contrats intelligents, ainsi que sur les mécanismes exacts pour gérer l'évolutivité dans chaque cas. C’est déjà assez complexe, et l’utilisation d’un modèle de sécurité distinct multiplie le nombre, ce qui rend presque impossible un suivi efficace.
C'est pourquoi nous considérons qu'un modèle de sécurité autonome constitue un risque de sécurité en soi, et nous supposons que chaque application qui utilisera ce modèle par défaut doit être considérée comme risquée jusqu'à preuve du contraire.
Prouver que des failles de sécurité existent
Nous avons décidé de tester notre hypothèse sur le réseau principal. Le framework LayerZero a été choisi pour l'expérimentation car il s'agit de l'une des solutions autonomes axées sur la sécurité les plus populaires. Nous avons déployé un jeton omnichain sécurisé et avons ensuite mis à jour la configuration de sécurité pour permettre les retraits malveillants du jeton. Le code du jeton est basé sur les exemples fournis par LayerZero et est très similaire ou identique à de nombreux autres jetons et applications omnichain déployés dans la vie réelle.
Mais avant d’entrer dans les détails, examinons brièvement à quoi ressemble le modèle de sécurité LayerZero.
Comme le souligne LayerZero dans son livre blanc, sa « communication inter-chaînes sans confiance » repose sur deux acteurs indépendants (oracles et relais) agissant ensemble pour assurer la sécurité du protocole.
LayerZero indique sur son site Web que son concept principal est « des applications utilisateur exécutant des terminaux ULN (UltraLightNode) configurables en chaîne ». Le composant en chaîne de LayerZero s'appuie sur deux composants externes hors chaîne pour relayer les messages entre les chaînes : les oracles et les relais.
Chaque fois qu'un message M est envoyé de la chaîne A à la chaîne B, les deux opérations suivantes se produisent :
Tout d'abord, l'oracle attend que la transaction envoyant le message M sur la chaîne A soit terminée, puis écrit les informations pertinentes sur la chaîne B, telles que la valeur de hachage de l'en-tête de bloc de la chaîne A contenant le message M (la valeur exacte entre les différentes chaînes/oracles Le format peut varier).
Le relais envoie ensuite une « preuve » (telle que Merkle Proof) à la chaîne B, prouvant que l'en-tête de bloc stocké contient le message M.
LayerZero suppose que les relais et les oracles sont des participants indépendants et honnêtes. Cependant, LayerZero a également déclaré dans le livre blanc que si cette hypothèse n'est pas satisfaite, par exemple, le relais et l'oracle s'entendent, ce qui entraîne que « l'en-tête de bloc fourni par l'oracle et la preuve de transaction fournie par le relais sont invalides, mais toujours correspondant. "
LayerZero affirme que « la conception de LayerZero élimine toute possibilité de collusion ». Mais en fait, cette affirmation est incorrecte (nous le prouvons dans les expériences présentées ci-dessous), car chaque application utilisateur peut définir ses propres relais et oracles. LayerZero ne garantit pas par conception que ces composants sont indépendants et ne peuvent pas s'entendre, il appartient plutôt à l'application utilisateur de fournir ces garanties ; LayerZero ne dispose d'aucun mécanisme pour arrêter les applications si elles choisissent de les interrompre.
De plus, par défaut, toutes les applications utilisateur peuvent changer de relais et d'oracles à tout moment, redéfinissant ainsi complètement les hypothèses de sécurité. Par conséquent, vérifier la sécurité d’une application donnée une seule fois n’est pas suffisant, car elle peut changer à tout moment après vérification, comme nous le montrerons dans nos expériences.
conception expérimentale
Pour nos expériences, nous avons décidé de créer un simple jeton omnichain, CarpetMoon, qui fonctionne à la fois sur Ethereum et Optimism et utilise LayerZero pour communiquer entre les deux chaînes.
Notre jeton utilise initialement le modèle de sécurité par défaut fourni par LayerZero, ce qui le rend identique aux grandes applications LayerZero actuellement déployées (peut-être pas toutes). Par conséquent, il est généralement aussi sûr que n’importe quelle autre pièce utilisant LayerZero.
Tout d’abord, nous déployons notre contrat de token sur Ethereum et Optimism :
https://ethtx.info/mainnet/0xf4d1cdabb6927c363bb30e7e65febad8b9c0f6f76f1984cd74c7f364e3ab7ca9/
https://optimistic.etherscan.io/tx/0xf41389d71fa3942de5225efb067072728c6c6de56c241574187781db7c73d221
Nous mettons ensuite en place le routage pour que LayerZero sache quel contrat correspond à quoi sur les deux chaînes.
https://ethtx.info/mainnet/0x19d78abb03179969d6404a7bd503148b4ac14d711f503752495339c96a7776e9/
https://optimistic.etherscan.io/tx/0x037b1bad33faa5607bb5835460a1d5caaf3a147dc3a09762ac7703befcdb3c3c
Le jeton a été déployé et il ressemble exactement à tous les autres jetons omnichain utilisant LayerZero, en utilisant la configuration par défaut et rien de louche.
Nous avons fourni 1 milliard de jetons CarpetMoon sur Ethereum à notre « utilisateur test » Alice.
https://ethtx.info/mainnet/0x7e2faa8426dacae92830efbf356ca2da760833eca28e652ff9261fc03042b313/
Désormais, Alice utilise LayerZero pour relier ces jetons à Optimism.
Nous verrouillons les tokens dans un contrat séquestre sur Ethereum :
https://ethtx.info/mainnet/0xe4dc3757b86bfda8e7baddc088fb1a599e083ed77034c29e5dd8bd11f1e17771/。
Le message contenant la transaction est transmis à Optimism via LayerZero :
https://layerzeroscan.com/101/address/0xc6005ccc1de4b300d538903b74848bff881d5dc5/message/111/address/0x201fe0d843b546f2e24d4c8444318d1c71b7nonced10d/。
Des jetons inter-chaînes sont créés sur Optimism, et Alice possède désormais 1 milliard de jetons MoonCarpet sur Optimism :
https://optimistic.etherscan.io/tx/0x5388ced88cf562acafff82d6798f791b0b38b90ee106df9bf91c0d86306ec302.
Tout fonctionne comme prévu, Alice croise les jetons et voit qu'il y a 1 milliard de jetons MoonCarpet dans le contrat séquestre sur Ethereum et 1 milliard de jetons MoonCarpet dans son compte chez Optimism. Mais juste pour s’assurer que tout allait bien, elle a retransféré la moitié de ses jetons vers Ethereum.
On commence par une transaction sur Optimism qui a brûlé 500 millions de tokens :
https://optimistic.etherscan.io/tx/0x118a57106488ad0bae1f3b920b1fd98b187752ad966f3a901fc53cff47f2097f。
Les informations sur la transaction sont transmises à Ethereum :
https://layerzeroscan.com/111/address/0x201fe0d843b546f2e24d4c8444318d1c71b7d10d/message/101/address/0xc6005ccc1de4b300d538903b74848bff881d5dc5/nonce/1.
Comme prévu, 500 millions de jetons MoonCarpet sont renvoyés du contrat séquestre à l'adresse d'Alice :
https://etherscan.io/tx/0x27702e07a65a9c6a7d1917222799ddb13bb3d05159d33bbeff2ca1ed414f6a18.
Jusqu'à présent, tout fonctionne bien et exactement comme prévu. Alice a vérifié qu'elle pouvait transférer des jetons d'Ethereum à Optimism et vice-versa, elle n'a aucune raison de s'inquiéter pour ses jetons MoonCarpet.
Mais les hypothèses ont leurs propres problèmes : par exemple, l'équipe derrière notre jeton rencontre des problèmes et le méchant Bob accède à la configuration LayerZero de notre application.
De cette façon, Bob peut modifier les oracles et les relais des composants par défaut en composants qu'il contrôle.
Il convient de noter qu'il s'agit d'un mécanisme fourni pour chaque application utilisant LayerZero et qu'il est ancré dans l'architecture de LayerZero. Il ne s'agit pas d'une porte dérobée d'aucune sorte, mais d'un mécanisme standard.
Alors Bob change l'oracle en un EOA sous son contrôle :
https://ethtx.info/mainnet/0x4dc84726da6ca7d750eef3d33710b5f63bf73cbe03746f88dd8375c3f4672f2f/。
Le répéteur est également modifié :
https://ethtx.info/mainnet/0xc1d7ba5032af2817e95ee943018393622bf54eb87e6ff414136f5f7c48c6d19a/。
Maintenant, quelque chose d’étrange se produit. Puisque l'oracle et le relais sont désormais sous le contrôle total de Bob, il est capable de voler les jetons d'Alice. Même si aucune mesure n'a été prise concernant Optimism (les jetons MoonCarpet étaient toujours dans le portefeuille d'Alice), Bob a réussi à convaincre le contrat intelligent MoonCarpet sur Ethereum (en utilisant le mécanisme LayerZero) qu'il avait détruit les jetons sur l'autre chaîne et il a pu retirez les jetons sur le jeton MoonCarpet sur Ethereum.
Tout d’abord, il met à jour le hachage de bloc d’Ethereum à l’aide d’un oracle qu’il contrôle :
https://ethtx.info/0xde2edee2cc7f070120e96c9df90d86696970befcfc221e18c6ac4168bb5b1d92/。
Il peut désormais retirer les jetons restants du contrat séquestre :
https://ethtx.info/0xda695f374b375d5372efeca37aae4c5a17f114d5a76db1e86edebb0924bcdcc7/。
Résultats expérimentaux
Alice ne sait même pas pourquoi et quand l'erreur s'est produite. Soudain, son jeton MoonCarpet sur Optimism n'était plus soutenu par des jetons sur Ethereum.
Le contrat intelligent n'est pas évolutif et fonctionne comme prévu. La seule activité suspecte concerne les changements d'oracle et de relais, mais il s'agit d'un mécanisme régulier intégré à LayerZero, donc Alice ne sait même pas si ce changement est intentionnel. Même si Alice apprend le changement, il est trop tard : l'attaquant peut drainer les fonds avant qu'elle ne puisse réagir.
Il n'y a rien que LayerZero puisse faire - ce sont toutes des implémentations efficaces de leurs mécanismes, sur lesquelles ils n'ont aucun contrôle. En théorie, les applications elles-mêmes pourraient s'empêcher de changer d'oracle et de relais, mais à notre connaissance, aucune application déployée ne l'a fait.
Nous avons fait cette expérience pour vérifier si quelqu’un l’avait remarqué, mais comme nous nous y attendions, personne ne l’a fait. Il est pratiquement impossible de surveiller efficacement toutes les applications créées avec LayerZero pour vérifier si leurs politiques de sécurité ont changé et alerter les utilisateurs lorsque cela se produit.
Même si quelqu’un parvient à découvrir à temps que les oracles et les relais ont changé et créent un risque pour la sécurité, il sera trop tard. Étant donné que les nouveaux oracles et relais sont désormais libres de choisir les messages à transmettre ou simplement de désactiver la communication inter-chaînes, les utilisateurs ne peuvent généralement pas faire grand-chose à ce sujet. Nos expériences montrent clairement que même si Alice remarque le changement de configuration de l'application, elle ne peut pas faire grand-chose avec ses jetons inter-chaînes - les nouveaux oracles et relais ne sont plus acceptés sur le message de la chaîne de communication d'origine, donc le message ne sera pas renvoyé à Ethereum. .
en conclusion
Comme nous pouvons le constater, même si notre jeton a été construit avec LayerZero et a utilisé ses mécanismes comme prévu, nous avons pu voler des fonds sur le séquestre du jeton. Bien sûr, c'est la faute de l'application (dans notre cas, le jeton CarpetMoon) et non de LayerZero lui-même, mais cela prouve que LayerZero lui-même n'offre aucune garantie de sécurité.
Lorsque LayerZero décrit son modèle de sécurité concernant les oracles et les relais, ils supposent que le propriétaire de l'application (ou quiconque possède la clé privée) ne fera rien de déraisonnable. Mais dans un environnement conflictuel, cette hypothèse est incorrecte. De plus, cela oblige les utilisateurs à faire confiance au développeur de l’application en tant que tiers de confiance.
Ainsi, dans la pratique, on ne peut faire aucune hypothèse sur la sécurité des applications créées avec LayerZero : chaque application doit être considérée comme risquée jusqu'à preuve du contraire.
En fait, toute l'histoire a commencé avec une communication publique selon laquelle nous prévoyions d'inclure tous les jetons omnichain sur le site Web de L2BEAT - nous avions du mal à comprendre comment évaluer leur risque. Lors de l’analyse des risques, nous avons eu l’idée de l’expérimentation.
Si L2BEAT était mis en ligne, la conséquence serait que nous devrions placer des alertes sur chaque application créée avec LayerZero pour avertir des risques de sécurité possibles. Mais nous souhaitions avoir une discussion plus large sur les modèles de sécurité car nous pensons que la sécurité autonome est un modèle qui devrait être évité, en particulier dans notre domaine.
Nous pensons qu’à mesure que les modèles de sécurité indépendants comme LayerZero deviennent plus populaires, de plus en plus de projets en abuseront, causant des dégâts massifs et augmentant l’incertitude dans l’ensemble du secteur.