paint-brush
Fuzzing Around : Test de contrat intelligent via des entrées aléatoirespar@alvinslee
1,279 lectures
1,279 lectures

Fuzzing Around : Test de contrat intelligent via des entrées aléatoires

par Alvin Lee5m2023/04/24
Read on Terminal Reader

Trop long; Pour lire

Le fuzzing est un moyen de bombarder votre code avec un tas d'entrées aléatoires juste pour voir ce qui se passe. C'est un moyen rapide, efficace et brutal de tester des cas et des scénarios extrêmes auxquels vous ne pensez peut-être pas. Diligence Fuzzing offre 10 heures de fuzzing gratuites pour essayer des choses.
featured image - Fuzzing Around : Test de contrat intelligent via des entrées aléatoires
Alvin Lee HackerNoon profile picture
0-item
1-item

Tester les contrats intelligents est vraiment important. Pourquoi? Les contrats intelligents sont généralement immuables en production, publics , cibles des hackers , et impliquent souvent des implications financières importantes . La petite histoire ? Avec les contrats intelligents, vous ne voulez pas vous tromper. Vous devez tester beaucoup, tester souvent et tester à fond. Les tests de contrat intelligents impliquent tous les suspects habituels - tests unitaires, tests d'intégration, tests automatisés - mais le fuzzing est également fortement recommandé - un moyen de bombarder votre code avec un tas d'entrées aléatoires juste pour voir ce qui se passe.


Voyons exactement ce qu'est le fuzzing en tant que méthode de test et comment vous pouvez facilement l'inclure dans votre flux de travail de test de logiciels à l'aide d'outils tels que ConsenSys Diligence Fuzzing . Nous allons parcourir un didacticiel en utilisant un exemple de contact intelligent defi pour voir comment cela se passe.


Qu'est-ce que le fuzzing testing et pourquoi devrais-je l'utiliser ?

Les tests fuzzing (ou tests fuzz) consistent à envoyer des millions de données invalides, inattendues et (semi) aléatoires contre un contrat intelligent dans le but de provoquer un comportement inattendu et de détecter les vulnérabilités. C'est un moyen rapide, efficace et brutal de tester des cas et des scénarios extrêmes auxquels vous ne pensez peut-être pas. Il complète vos autres flux de test et vos audits.


Le fuzzing existe depuis un certain temps dans le développement traditionnel de la pile complète, mais une nouvelle classe d'outils est là qui peut appliquer le fuzzing aux tests de contrats intelligents dans le web3. Certains des outils de fuzzing incluent l'open source Echidna et MythX .


Dans cet article, cependant, je vais plonger en profondeur dans Diligence Fuzzing , qui propose le fuzzing en tant que service, un moyen assez cool et facile de fuzzer.


Pour utiliser Diligence Fuzzing, vous annotez vos contrats intelligents à l'aide de Scribble . Fondamentalement, vous utilisez des annotations Scribble dans votre code pour indiquer au fuzzer le type de sortie à attendre pour cette fonction.


Cela ressemble à ceci :


 /// #invariant {:msg "balances are in sync"} unchecked_sum(_balances) == _totalSupply;


Vous appelez le fuzzer à partir d'une interface utilisateur Web où vous soumettez le code de contrat intelligent. Vous appuyez sur Exécuter et environ 10 minutes plus tard, vous obtenez un rapport avec les problèmes détectés, l'emplacement des problèmes, le pourcentage de couverture, etc.


Il s'agit d'un moyen simple et puissant de vérifier certains cas extrêmes.

Tester un contrat intelligent DeFi

Disons que nous avons un nouveau protocole DeFi et un jeton correspondant que nous voulons lancer. DeFi est une finance de pointe, amusante à écrire, et il est essentiel que nous n'ayons aucun bogue. Les contrats intelligents DeFi impliquent souvent des millions (ou plus) de fonds d'utilisateurs. Nous voulons donc nous assurer que nos contrats intelligents sont testés (et audités) aussi minutieusement que possible.


REMARQUE IMPORTANTE : ce code contient des vulnérabilités VOLONTAIRES ! C'est pour montrer comment le fuzzing peut détecter ces erreurs. S'il vous plaît, n'utilisez pas vraiment ce code pour quoi que ce soit.


Commençons.


Un exemple utilisant le Diligence Fuzzing (FaaS)

Étape 1 : Créez un compte Diligence.

Tout d'abord, nous avons besoin de notre compte Diligence. Inscrivez-vous sur Diligence . Vous bénéficiez de 10 heures de fuzzing gratuites pour essayer des choses.

Étape 2 : Créez une nouvelle clé d'API.

Cliquez sur le nom de votre compte en haut à droite, cliquez sur "créer une nouvelle clé API" et donnez-lui un nom. Cette clé API nous permet de nous connecter au FaaS.





Étape 3 : Configurez votre environnement local.

Clonez le dépôt suivant :

https://github.com/ConsenSys/scribble-exercise-1.git


À partir de la ligne de commande, accédez au dossier du référentiel, qui sera désormais le dossier racine de votre projet. Si nécessaire pour votre machine, activez un Python venv. Ensuite, exécutez les commandes suivantes pour installer les dépendances de votre projet :


 $ npm i -g eth-scribble ganache truffle $ pip3 install diligence-fuzzing

Étape 4 : Saisissez votre clé API.

Modifiez le fichier .fuzz.yml pour utiliser la clé API de votre compte Diligence comme valeur de clé.

Votre fichier résultant devrait ressembler à ceci :


 .fuzz.yml fuzz: # Tell the CLI where to find the compiled contracts and compilation artifacts build_directory: build/contracts ... campaign_name_prefix: "ERC20 campaign" # Point to your ganache node which holds the seed rpc_url: "http://localhost:8545" key: "DILIGENCE API KEY GOES HERE" ...

Étape 5 : Rédigez et annotez votre contrat.

Voyons maintenant notre contrat intelligent sur contracts/vulnerableERC20.sol . Ici, nous avons un jeton vulnérable (comme il est nommé !) pour notre nouveau protocole DeFi. Nous devons clairement le tester autant que possible. Ajoutons donc une vérification à l'aide de Scribble que le fuzzer attrapera, espérons-le.


Au-dessus de la définition du contrat, ajoutez :


 /// #invariant "balances are in sync" unchecked_sum(_balances) == _totalSupply;


Et au-dessus de la fonction de transfert, ajoutez :


 /// #if_succeeds msg.sender != _to ==> _balances[_to] == old(_balances[_to]) + _value; /// #if_succeeds msg.sender != _to ==> _balances[msg.sender] == old(_balances[msg.sender]) - _value; /// #if_succeeds msg.sender == _to ==> _balances[msg.sender] == old(_balances[_to]); /// #if_succeeds old(_balances[msg.sender]) >= _value;


Voyons maintenant si le testeur de fuzz détecte quelque chose. Notez les annotations que nous avons ajoutées au contrat pour aider le testeur à comprendre ce que nous attendons. Et notez que dans la configuration, le testeur est configuré pour fonctionner pendant 10 minutes maximum, il se peut donc qu'il ne capte pas tout.

Étape 6: Fuzz autour.

Nous sommes maintenant prêts à tester ! À partir du dossier racine du projet, exécutez make fuzz pour appeler le fichier make, qui compilera, construira et enverra tout au FaaS.

Étape 7 : Voir les résultats.

Revenez à votre tableau de bord et vous devriez voir quelque chose de similaire à ce qui suit. Attendez quelques secondes que la campagne démarre.



Une fois la génération terminée, vous devriez voir quelque chose de similaire à ce qui est illustré ci-dessous :

Nous voyons même la couverture du code !



Et au bout de quelques minutes, on constate un échec !


En cliquant sur les propriétés, nous voyons toutes les violations. Et oui nous avons un bug ! Cliquez sur l'emplacement de la ligne pour voir les détails de nos vulnérabilités potentielles de code.



On s'arrêtera là, mais si vous laissez le fuzzer continuer à fonctionner, il en trouvera peut-être plus !


Conclusion

Le fuzzing peut être une étape cruciale dans votre processus de développement et de test de logiciels. Il vous aide à identifier les vulnérabilités potentielles qui, autrement, pourraient passer inaperçues. En l'utilisant, vous commencez à reconnaître et à comprendre les pièges et les défis courants. Profitez d'outils tels que Diligence Fuzzing , rédigez de meilleurs contrats intelligents et devenez un meilleur développeur !