Incidents associés
Réflexions sur le piratage DAO
Nous venons de vivre le scénario cauchemardesque qui nous inquiétait lorsque nous avons appelé à un moratoire sur The DAO : quelqu'un a exploité une faiblesse dans le code de The DAO pour vider plus de 2 millions de dollars (40 millions de dollars) d'éther.
L'exploit semble avoir ciblé le problème de réentrance dans la fonction 'splitDAO'. Le problème de réentrance est lié mais distinct du problème d'envoi non vérifié qui a été discuté sur ce blog hier. Les deux problèmes sont bien connus, identifiés par l'audit de la moindre autorité de la machine virtuelle Ethereum comme des problèmes pouvant affecter les applications, ainsi que par le récent article de blog de Peter Vessenes. Essentiellement, un appel qui ressemble à un appel normal peut facilement être transformé en un appel récursif, et à moins que l'application ne soit codée très soigneusement, elle peut être utilisée pour effectuer plusieurs retraits alors qu'un seul devrait être autorisé. Il semble que l'agresseur en ait profité pour retirer des sommes conséquentes.
Mes réactions immédiates à ce hack sont les suivantes.
Qu'est-ce qu'un hack quand vous n'avez pas de spécification ? Tout d'abord, je ne suis même pas sûr que cela soit considéré comme un hack. Pour étiqueter quelque chose comme un piratage ou un bogue ou un comportement indésirable, nous devons avoir une spécification du comportement souhaité. Nous n'avions pas de telles spécifications pour le DAO. Il n'y a pas de spécification indépendante pour ce que le DAO est censé implémenter. Heck, il n'y a pratiquement aucun commentaire dans le code DAO qui documente ce que les développeurs ont pu penser au moment où ils ont écrit le code. Le "code était sa propre documentation", comme on dit. C'était ses propres petits caractères. Le hacker a lu les petits caractères mieux que la plupart, mieux que les développeurs eux-mêmes. Si l'attaquant avait perdu de l'argent par erreur, je suis sûr que les développeurs n'auraient eu aucune difficulté à s'approprier ses fonds et à dire "c'est ce qui se passe dans le nouveau monde des flux d'argent programmatiques". Quand il a plutôt vidé les pièces du DAO, la seule réponse cohérente est de l'appeler un travail bien fait.
Pas de refuge pour le moment Vous pourriez penser que, face à un attaquant sur The DAO, vous pourriez simplement prendre vos fonds et être en sécurité. Mais ce n'est pas le cas ici. Les développeurs de DAO ont décidé de rendre difficile le retrait de fonds de The DAO. Ils n'ont donc pas donné aux gens la possibilité de "simplement retirer des fonds". Au lieu de cela, un investisseur DAO peut créer un nouveau "enfant DAO" et transférer ses fonds dans l'enfant et les y conserver pendant 27 jours - il n'y a pas de retrait direct. Le problème est que le DAO enfant est exactement le même code que le parent et a exactement la même vulnérabilité. Reconvertir l'enfant en éther prend encore 34 jours; le remplacement du DAO enfant par un contrat upgradé prend au minimum 7 jours. Ainsi, l'attaquant, s'il le souhaitait, pourrait traquer les gens dans les DAO de leurs enfants et les drainer avant qu'ils n'aient la possibilité de mettre à niveau leurs contrats. Je ne pense pas qu'il le fera : s'il s'élevait à ce niveau d'odieux, il invoquerait certainement une censure spécifique.
Déplacer des fonds a un coût Le DAO n'a pas été conçu pour avoir une fonction de "mise à jour" facile. En particulier, en ce moment, il semble n'y avoir aucun moyen de retirer le DAO de son état actuel et de le réintégrer dans un nouveau code de contrat, en gardant son état interne intact. Le compte "extraBalance", en particulier, n'est pas transférable via les mises à niveau "newContract". Cela signifie que le montant extraBalance, d'une valeur de quelques millions de dollars, est une radiation.
L'expérience DAO est terminée Pratiquement, cela devrait marquer la fin de The DAO. Les gens de SlockIt devraient travailler dur pour démanteler le fonds et rendre les pièces aux investisseurs de la manière la plus ordonnée possible.
Ethereum/Solidity convient-il aux contrats intelligents sécurisés ? Il est clair que la rédaction d'un contrat intelligent robuste et sécurisé nécessite une diligence extrême. Cela ressemble plus à l'écriture de code pour un réacteur nucléaire qu'à l'écriture de code Web libre. Pourtant, le langage Solidity actuel et l'EVM sous-jacent semblent davantage conçus pour ce dernier. Voici quelques défauts : Un bon langage pour écrire des machines à états garantirait qu'il n'y a pas d'états dont il est impossible de récupérer.
Un bon langage pour écrire des machines à états rendrait douloureusement clair quand les transitions d'état peuvent et ne peuvent pas se produire.
Un bon langage pour maintenir les machines d'état fournirait des fonctionnalités pour améliorer la sécurité d'un contrat en direct.
Un bon langage pour écrire du code sécurisé indiquerait clairement qu'il n'y a pas d'actions implicites, que le code s'exécute clairement, tel qu'il est lu. Le langage actuel ne remplit aucun de ces commandements, et en fait, le dernier, impliquant des appels récursifs implicites, est ce qu'a fait The Dao. L'équipe SlockIt a même demandé au concepteur et à l'implémenteur de Solidity d'effectuer une révision de leur code. S'il ne peut pas sécuriser quelque chose comme le DAO, personne ne le peut. Une réflexion semble s'imposer.
Attaques imitatrices La principale inquiétude concerne actuellement les attaques imitatrices. D'autres peuvent apprendre de cette attaque et lancer exactement la même.
Arrêter l'attaquant La grande inconnue est la réaction de la communauté Ethereum. D'une part, faire reculer l'ethereu