Analyse des contrats Ethereum en direct pour une erreur d'envoi non contrôlé. 2e partie

Suite de l'article «Analyse des contrats Ethereum en direct pour l'erreur d'envoi non contrôlé». Partie 1 " .


Il y a presque un an (alors qu'Ethereum était dans sa version «frontière»), le populaire contrat de loterie EtherPot [9] a également souffert de la même erreur. Une version antérieure de BTCRelay a également montré cette erreur [7] . Bien qu'un danger ait été détecté lors d'un précédent audit de sécurité, une correction incorrecte a d'abord été appliquée [8] .


Détection d'erreur d'envoi non contrôlé sur la blockhain en direct


Quelle est la fréquence de ces erreurs? Écoutent-ils les avertissements? Les meilleures pratiques sont-elles appliquées? Nous répondons empiriquement à ces questions en analysant les données de la chaîne de blocs Ethereum, ainsi que le référentiel de code Solidity trouvé sur etherscrape.com. Pour ce faire, nous développons un outil d'analyse de programme simple qui vérifie le contrat de chaîne de blocs et utilise une heuristique pour vérifier si l'une des méthodes de protection les plus efficaces est utilisée. Le listing 2 montre la première technique de sécurité, comme recommandé dans la documentation Ethereum, qui devrait vérifier la valeur de retour de send et lever une exception. Pour détecter l'utilisation de cette méthode, nous utilisons une approximation grossière: il suffit de regarder si la valeur de retour de send est ignorée ou non.

Le listing 4 illustre la deuxième technique de sécurité recommandée dans le manuel UMD, qui vérifie directement si la pile d'appels est pleine en envoyant un message de test. Pour découvrir cette technique, nous utilisons à nouveau une approximation grossière: nous vérifions simplement si un message est envoyé en plus de la commande send .

Si aucun de ces indicateurs heuristiques n'est présent, nous concluons qu'aucune des recommandations de meilleures pratiques n'est suivie. Nous implémentons ces heuristiques en utilisant une correspondance de modèle simple avec un bytecode EVM compilé. Plus de détails sur la façon dont nous procédons peuvent être trouvés dans l'annexe [12] .


Combien de contrats sont vulnérables?


Commençons par vérifier l'heuristique dans le référentiel Etherscrape du code source Solidity. Au 20 mars 2016, le relais Etherscrape contenait 361 programmes de contrat Solidity, dont 56 contenaient une déclaration d'envoi. De ces programmes sous contrat, nous supposons que la plupart (au moins 36 sur 56) n'utilisent aucune des méthodes de programmation défensive.

Même si le contrat n'utilise aucune des technologies de protection, il peut ou non présenter une réelle vulnérabilité. Nous avons vérifié manuellement les contrats Solidity pour confirmer la vulnérabilité. Pour nos besoins, nous considérons un contrat vulnérable si son état peut changer même si la commande send ne fonctionne pas (nous allons donc regarder le code vulnérable dans le Listing 5). Nous avons confirmé que la grande majorité des vulnérabilités sont présentes, 32 sur 36 de ces contrats.


De même, notre heuristique ne garantit pas l'application correcte de la programmation défensive. Prenons, par exemple, WeiFund, un DApp de crowdfunding open source décentralisé. Ce contrat a deux fonctions: remboursement () et paiement () , ce qui trompe notre heuristique. Ce qui suit est un extrait du remboursement .


function refund(uint _campaignID, uint contributionID) public { ... receiver.send(donation.amountContributed); donation.refunded = true; ... if(c.config != address(0)) WeiFundConfig(c.config).refund(_campaignID, donation.contributor, donation.amountContributed); } 

Dans ce code, un message est envoyé à WeiFundConfig (c.config) pour invoquer la méthode de remboursement, mais uniquement sous certaines conditions. Si c.config est une valeur nulle, le contrat est vraiment vulnérable à une attaque par pile d'appels. Lors de la vérification *, aucun des programmes Solidity qui ont réussi nos tests heuristiques n'a appliqué directement la meilleure pratique de test de pile d'appels recommandée. *

Ensuite, nous tournons notre attention vers les projets de contrats sur la chaîne de blocs vivants Ethereum. Nous avons regardé l'image datée du 20 mars 2016 (horodatage: 1184243). Cet instantané contient un total de 13645 chaînes de blocs, qui sont apparemment générées par le compilateur Solidity, dont seulement 1618 (11,8%) incluaient la commande d' envoi .

Parmi ceux-ci, la grande majorité ne semble utiliser aucune des techniques de programmation défensive.


Qu'en est-il du problème de course récursive dans TheDAO? Le contrat intelligent le plus excitant de nos jours, TheDAO [11] , souffre d'une erreur complètement distincte, à savoir qu'il n'est pas «sûr pour une réutilisation» [13] . Il s'agit d'un autre type (connecté, mais distinct) de programmation non sécurisée, qui était également prévu lors des précédents contrôles de sécurité [6] , mais, comme auparavant, il est probable que de nombreux contrats ne sont pas sûrs aujourd'hui. Les travaux futurs consistaient à créer un outil qui pourrait également détecter une telle erreur.


Où tout s'est-il mal passé?


Nous ne nous attendons pas à ce que la programmation sur les contrats intelligents soit complètement simple, du moins pour l'instant. Cependant, il est surprenant que cette forme particulière d'erreur soit si répandue, malgré le fait qu'elle ait été décrite il y a si longtemps lors du développement de l'écosystème Ethereum.

Un rapport de 2015 [6] a fait cette recommandation aux développeurs d'Ethereum: "

Actuellement, les exemples de programmation présentés dans la documentation sont insuffisants pour diffuser les meilleures pratiques pour la rédaction de contrats sécurisés et la résolution du problème du mécanisme de gaz. Les didacticiels d'introduction C ++ sautent souvent
vérification des erreurs de lisibilité, qui a conduit à de nombreuses erreurs de sécurité. Les exemples d'Ethereum devraient enseigner les meilleures habitudes. Recommandation: fournir encore plus d'exemples de programmation minutieuse des contrats de sécurité. "

Nous ne connaissons qu'une seule réponse officielle à cette question, qui consiste à ajouter un avertissement à la documentation officielle de Solidity mentionnée précédemment [3], répétée ci-dessous: 1024 (cela peut toujours être appelé par l'appelant), et échoue également si le destinataire manque de gaz, donc pour assurer une diffusion en toute sécurité, vérifiez toujours la valeur de retour de l' envoi ou encore mieux: utilisez le modèle dans lequel le destinataire retire de l'argent. "


Nous pensons que cette observation n'est pas suffisante pour documenter le problème. Il n'offre qu'une atténuation incomplète et ne décrit qu'une seule version du danger, ce qui pourrait induire le lecteur en erreur quant à son degré.


  • Mise à jour:
    L'insuffisance de la documentation de Solidity a également été illustrée en détail par Peter Wesenes. [16]


De plus, l'avertissement semble souvent ignoré. Par conséquent, nous pensons que des mesures préventives supplémentaires sont nécessaires.



Comment Etherscrape peut-il aider?


Nous pensons que l'utilisation d'outils d'analyse statique, même grossiers, tels que ceux décrits dans cet article, peut aider à améliorer la qualité des contrats intelligents. Chez Etherscrape, nous intégrons des outils d'analyse comme celui-ci dans notre service Web public, et nous ajoutons un lien vers la page de l'outil quand elle sera prête. Cela facilitera la visualisation du code de contrat intelligent en mettant en évidence les endroits où des erreurs peuvent se produire. Nous supposons que les utilisateurs d'un tel contrat intelligent (par exemple, les investisseurs potentiels dans TheDAO ou ses offres) peuvent facilement utiliser des outils tels que la vérification de l'intégrité avant de déposer leur argent. Même les investisseurs non techniques peuvent tenir les développeurs responsables pour expliquer comment ils ont réagi aux problèmes notés dans le code.

Etherscrape aide également en analysant la chaîne de blocs publique et en contrôlant la prévalence de cette erreur, ce qui peut aider à décider, par exemple, combien d'argent doit être alloué pour la recherche et le développement d'outils d'analyse statique. De plus, des compilateurs tels que solc peuvent intégrer de telles analyses, prévenant le programmeur lorsqu'une erreur semble probable.


Lecture recommandée



Source: https://habr.com/ru/post/fr430684/


All Articles