Incidents associés
La combinaison tragique de bugs inévitables et de code immuable
La semaine dernière a été témoin d'un événement catastrophique dans l'écosystème Ethereum, lorsque le DAO, un contrat intelligent vieux de moins de deux mois, a commencé à divulguer rapidement des fonds à une partie inconnue. En regardant l'ensemble actuel de contrats Ethereum, rempli de casinos et de schémas de Ponzi autodéclarés, cela peut ne pas sembler être un gros problème. C'est-à-dire jusqu'à ce que vous appreniez que plus de 12 millions d'unités d'éther, la crypto-monnaie Ethereum, avaient été investies dans The DAO par près de 20 000 personnes. Cela représente environ 15% de tout l'éther existant, évalué à plus de 250 millions de dollars le 17 juin.
Deux jours plus tard, les actifs du DAO sont tombés en dessous de 100 millions de dollars. Deux choses ont contribué à cette chute vertigineuse. Premièrement, un tiers de ses fonds (libellés en éther) avait déjà été pris. Et deuxièmement, la panique qui en a résulté a fait chuter le prix du marché de l'éther de son sommet de plus de 21 $ à 10,67 $, ce qui donne à réfléchir. (Au moment de la publication, le prix était revenu à environ 14 $.) Ce deuxième effet était une conséquence naturelle du premier, car une grande partie de la récente augmentation de la valeur de l'éther était due aux personnes qui l'achetaient pour investir dans The DAO.
Le DAO avait promis d'agir comme un nouveau type de véhicule de crowdsourcing décentralisé, comme Kickstarter ou Indiegogo mais sans intermédiaire ni réglementation. Il a été conçu pour permettre aux participants de mettre en commun leur crypto-monnaie, de voter collectivement sur des projets à la recherche de financement, puis d'investir et de récolter les récompenses futures. Avant que la catastrophe ne frappe, plus de 100 projets avaient déjà été proposés, dont la plupart étaient liés à Ethereum lui-même. De plus, le DAO permettait aux participants de retirer leurs fonds non investis à tout moment, se positionnant comme un investissement à faible risque.
Ironiquement, l'individu ou le groupe qui a vidé le DAO l'a fait en exploitant des erreurs subtiles dans ce mécanisme de retrait. Comme tous les contrats intelligents dans Ethereum, le DAO n'est qu'un morceau de code informatique, qui est "immuablement" (c'est-à-dire de manière permanente et irréversible) intégré dans la blockchain et exécuté par chaque nœud en réponse aux transactions entrantes. Et comme tout contrat intelligent qui se respecte, The DAO offre une transparence totale en rendant son code source facilement accessible en ligne. Cela signifie que n'importe qui peut vérifier indépendamment sa fonctionnalité mais aussi, surtout, rechercher des vulnérabilités. Et pourtant, la nature immuable des blockchains empêche la résolution de tels problèmes.
Fin mai, plusieurs problèmes critiques ont été mis en évidence sur l'excellent blog Hacking Distributed, parallèlement à un appel à un moratoire sur les propositions de projets pour The DAO. C'est ce que l'on pourrait appeler l'approche du "chapeau blanc", dans laquelle les exploits sont signalés pour le bien de la communauté. Néanmoins, personne ne semblait trop inquiet, car les problèmes étaient liés à des incitations économiques biaisées plutôt qu'à un risque de vol pur et simple. Simultanément, cependant, il semble que d'autres se penchaient sur le code du DAO avec un plus grand intérêt personnel, à savoir chercher un moyen de gagner une tonne d'argent. Et le 17 juin, quelqu'un a réussi.
Vidange du DAO
De manière générale, l'attaque est née de l'interaction entre les vulnérabilités du code du DAO et d'autres codes conçus pour les exploiter. Vous voyez, vu isolément, le DAO ne contenait aucune erreur évidente, et en effet il n'a été publié qu'après un audit de sécurité approfondi. Mais avec le recul et beaucoup plus d'yeux, un nombre important d'erreurs ont depuis été découvertes.
Je ne fournirai pas ici une description technique complète du mécanisme de l'exploit, car d'autres ont déjà publié de superbes post mortem détaillés (voir ici, ici et ici). Mais je vais expliquer une vulnérabilité particulière qui était présente, car elle a été découverte dans de nombreux autres contrats intelligents et sert d'exemple instructif.
Disons qu'un contrat intelligent détient des fonds pour le compte d'un certain nombre d'utilisateurs et permet à ces utilisateurs de retirer leurs fonds sur demande. La logique du processus pourrait ressembler à ceci :
Attendez qu'un utilisateur demande un retrait. Vérifiez si le solde de cet utilisateur est suffisant. Si oui, envoyez la quantité demandée à l'adresse de l'utilisateur. Vérifiez que le paiement a réussi. Si c'est le cas, déduisez la quantité du solde de l'utilisateur.
Tout cela semble éminemment sensé et ressemble plutôt à un guichet automatique qui vous donne de l'argent et déduit le montant approprié de votre solde bancaire.
Alors, comment ce processus simple peut-il mal tourner ? Eh bien, il s'avère que si une adresse Ethereum appartient à un contrat plutôt qu'à un utilisateur régulier, alors ce contrat peut exécuter du code en réponse à la réception de fonds. Et ce code peut, à son tour, déclencher d'autres morceaux de code sur la blockchain Ethereum. Surtout, il peut même déclencher le même morceau de code qui l'a fait payer en premier lieu.
Cela signifie que, lors de l'étape 3 ci-dessus, l'adresse de réception peut envoyer une nouvelle demande de retrait, en commençant un nouveau processus à l'étape 1 avant que le processus précédent ne soit terminé. Étant donné que le solde de l'utilisateur n'est réduit qu'à l'étape 5, un nouveau prélèvement sera