Vulnérabilités potentielles des contrats intelligents

Bien qu’innovants, les contrats intelligents ne sont pas à l’abri des failles que des parties malveillantes pourraient exploiter.

Une validation inadéquate des entrées est une faiblesse répandue qui permet aux attaquants d’affecter l’exécution du contrat en fournissant des entrées inattendues. De plus, une mauvaise application de la logique métier peut entraîner des vulnérabilités en créant des comportements inattendus ou des lacunes logiques dans le contrat. De plus, s'ils sont mal gérés, les appels externes non sécurisés, tels que ceux impliquant des interfaces avec des sources de données externes ou d'autres contrats, peuvent présenter des vulnérabilités.

Les attaques de réentrance sont des faiblesses qui se produisent lorsqu'un contrat appelle un autre contrat en externe avant d'effectuer ses propres changements d'état. Cela permet au contrat appelé de réintégrer le contrat appelant et peut-être d'effectuer à nouveau certaines de ses opérations. Cela peut entraîner des actions imprévues et permettre aux attaquants de modifier l’état du contrat, épuisant ainsi les fonds ou ayant d’autres effets négatifs.

Compte tenu de la possibilité de telles attaques, les développeurs doivent également faire preuve de prudence lorsqu'ils travaillent avec des contrats ou des sources de données externes, en s'assurant que les appels externes sont traités correctement afin d'éviter des comportements inattendus et des vulnérabilités. Ils peuvent aider à protéger les contrats intelligents contre l’évolution des menaces en accordant une attention particulière aux procédures de sécurité telles que les tests de contrats intelligents.

Que sont les attaques de réentrée dans les contrats intelligents ?

Dans les contrats intelligents, les attaques de réentrance se produisent lorsqu'un contrat appelle un autre contrat ou fonctionne en externe avant de terminer ses propres changements d'état.

Cela permet au contrat appelé de réintégrer le contrat appelant et éventuellement d'effectuer à nouveau une partie de ses opérations, ce qui peut entraîner des comportements imprévus et souvent malveillants. Par exemple, une situation dans laquelle le contrat A appelle le contrat B pour envoyer des fonds puis modifie son propre état.

Le code du contrat B peut contenir une fonction de rappel qui lui permet de réintégrer le contrat A et éventuellement de réexécuter la fonction de transfert avant que le contrat A ne termine ses changements d'état. Cela permettrait à l'attaquant de retirer de l'argent du contrat A plusieurs fois avant de finaliser la transaction initiale.

Le tristement célèbre piratage de la blockchain Ethereum par une organisation autonome décentralisée (DAO) en 2016 est un autre exemple bien connu. Un attaquant a supprimé de manière récursive des fonds du DAO en profitant d'une faille de réentrée dans le code du contrat intelligent, ce qui a finalement abouti au vol de millions de dollars d'Ether (ETH).

De plus, plusieurs protocoles de finance décentralisée (DeFi), notamment Uniswap, Lendf.Me, BurgerSwap, SURGEBNB, Cream Finance et Siren Protocol, ont subi des pertes financières importantes en raison d'exploits de réentrée. Ces violations ont entraîné des pertes allant de 3,5 millions de dollars à 25 millions de dollars, soulignant la menace persistante posée par les vulnérabilités de réentrée dans l'espace DeFi.

Comment fonctionnent les attaques de réentrée

Les attaques de réentrée utilisent l'exécution séquentielle de fonctions de contrats intelligents ainsi que des appels externes pour former une boucle dans laquelle les attaquants peuvent exécuter des fonctions spécifiques plusieurs fois avant de les terminer, ce qui peut entraîner des comportements malveillants et des retraits de fonds non approuvés.

Avant que la victime n’ait terminé ses modifications d’état, le contrat de l’attaquant « trompe » effectivement le contrat de la victime pour qu’il rappelle le contrat de l’attaquant. Des retraits récurrents ou d’autres comportements négligents peuvent résulter de cette action.

L'image ci-dessus montre une attaque de réentrance sur un contrat intelligent. Le contrat de l’attaquant appelle la fonction « withdraw() » de la victime, qui envoie de l’Ether avant de mettre à jour le solde. La fonction de secours de l’attaquant est alors déclenchée, appelant à nouveau de manière récursive Remove() pour drainer les fonds du contrat de la victime. Cette attaque exploite l’incapacité de la victime à mettre à jour son solde avant d’envoyer des fonds.

Décomposons le fonctionnement des attaques par réentrée à l'aide d'un exemple simplifié :

Contrat intelligent avec fonction « retirer »

Supposons qu’il existe un contrat intelligent de portefeuille numérique qui permet aux utilisateurs de retirer des fonds. En plus de garder une trace des soldes des utilisateurs, ce contrat dispose d'une fonction de retrait qui facilite le retrait des fonds. La fonction de retrait permet généralement aux utilisateurs de retirer leurs jetons ou Ether du contrat intelligent vers leur portefeuille personnel.

Interaction de l'utilisateur et exécution des fonctions

Un utilisateur demande lui-même un retrait de son portefeuille. Ils utilisent la fonction de retrait pour saisir le montant de retrait souhaité.

La fonction de retrait vérifie si l'utilisateur dispose de suffisamment d'argent pour effectuer un retrait lorsqu'elle est appelée. Il transfère les fonds requis à l’adresse sélectionnée par l’utilisateur si les exigences sont satisfaites.

Appel externe

C’est là que la faiblesse apparaît. Avant que le retrait ne soit reflété sur le solde de l’utilisateur, le contrat effectue un appel externe vers un autre contrat ou compte.

Appel récursif

Si le code du contrat externe inclut une fonction qui peut rappeler le contrat d'origine (comme une autre fonction de retrait), alors une boucle récursive est créée. Cela permet d'appeler à nouveau la méthode de retrait avant qu'elle ne se termine.

Exploitation de la réentrée

Un attaquant utilise alors un contrat malveillant pour profiter de cette boucle. Le contrat de l’attaquant appelle rapidement à nouveau la fonction de retrait du portefeuille avant la mise à jour du solde lors de l’invocation du contrat externe par le contrat du portefeuille.

Fonction de repli

Dans certaines situations, la fonction de secours d’un contrat intelligent – ​​une fonctionnalité unique qui entre en jeu lorsque le contrat reçoit un appel sans aucune donnée ni Ether – peut être utilisée par l’attaquant. Les attaques de réentrée peuvent être menées en invoquant à plusieurs reprises la fonction de repli pendant que les fonds sont encore en cours de traitement.

Manipulation de l’État et retraits répétés

Le contrat de l’attaquant peut utiliser à plusieurs reprises la fonction de retrait au sein de la même transaction, car le contrat du portefeuille retarde la mise à jour des soldes jusqu’à la réception d’appels externes. En conséquence, cela facilite le retrait de fonds sans autorisation, permettant ainsi à l’attaquant de voler plus que ce à quoi il a légalement droit. Par la suite, cela inflige des pertes financières substantielles aux utilisateurs du contrat de portefeuille.

Conséquences des attaques de réentrée

Les attaques par réentrée ont de graves conséquences pour les utilisateurs de contrats intelligents, en raison de leur potentiel à causer des pertes financières substantielles.

L’une des conséquences les plus immédiates d’une attaque de réentrée est le retrait non autorisé ou la manipulation d’espèces conservées dans un contrat intelligent vulnérable. Les attaquants exploitent cette vulnérabilité pour retirer à plusieurs reprises des fonds du contrat, épuisant ainsi son solde et pouvant causer des pertes financières importantes aux utilisateurs qui ont investi ou stocké des actifs dans le contrat concerné.

En outre, la confiance des utilisateurs dans la sécurité et l’intégrité des contrats intelligents et de la technologie blockchain en général peut être affaiblie par les attaques de réentrée. Les vulnérabilités de réentrée peuvent avoir des effets désastreux, comme le démontrent des événements très médiatisés comme le piratage DAO de la blockchain Ethereum en 2016, qui a causé d’énormes pertes financières et nui à la réputation de la communauté.

Au-delà des conséquences financières à court terme, les attaques par réentrée peuvent avoir des effets à plus long terme, tels qu’une attention réglementaire et juridique, une perte de confiance des investisseurs et une atteinte à la réputation des plateformes et des projets blockchain. La perception de vulnérabilité aux attaques peut inciter les utilisateurs à être prudents lorsqu’ils interagissent avec des contrats intelligents ou investissent dans des applications décentralisées (DApps), entravant ainsi l’adoption et l’expansion de la technologie blockchain.

Comment atténuer les attaques de réentrée

La mise en œuvre des meilleures pratiques en matière de création et d’audit de contrats intelligents est nécessaire pour atténuer les menaces de réentrée.

Cela inclut l’utilisation de bibliothèques de codes bien connues et ayant fait leurs preuves en matière de sécurité, ce qui est une façon de procéder. Ces bibliothèques ont été soumises à des tests approfondis et à un examen par les pairs, ce qui réduit le risque d'introduction de vulnérabilités.

Les développeurs doivent également utiliser des contrôles de sécurité tels que la conception « contrôles-effets-interaction », qui minimise les risques d'attaques de réentrance en garantissant que les modifications d'état se produisent de manière atomique. Une ligne de défense supplémentaire contre de telles vulnérabilités peut être ajoutée en utilisant des cadres de développement de contrats intelligents sécurisés par la réentrée s'ils sont disponibles.

Les développeurs sont moins susceptibles de devoir ajouter manuellement des protections de sécurité, car ces frameworks incluent souvent des méthodes et des garanties intégrées expressément conçues pour éviter les attaques de réentrance. Cependant, comme la sécurité de la blockchain est encore en développement, les développeurs doivent continuer à être à l’affût de nouvelles menaces et faiblesses.