Analyse des vulnérabilités du compilateur Solidity : impacts, cas et stratégies d'atténuation

Analyse des vulnérabilités du compilateur Solidity et stratégies d'atténuation

Le compilateur est l'un des éléments fondamentaux des systèmes informatiques modernes. C'est un programme informatique dont la fonction est de convertir le code source écrit dans un langage de programmation de haut niveau, facile à comprendre et à écrire pour les humains, en instructions exécutables par le CPU ou la machine virtuelle à bytecode.

La plupart des développeurs et des spécialistes de la sécurité se concentrent généralement sur la sécurité du code des applications, mais peuvent négliger la sécurité du compilateur lui-même. En réalité, le compilateur, en tant que programme informatique, peut également présenter des vulnérabilités de sécurité, et les failles de sécurité générées par le compilateur peuvent, dans certains cas, entraîner des risques de sécurité graves. Par exemple, lors de la compilation et de l'analyse de l'exécution du code JavaScript côté client par le navigateur, des vulnérabilités dans le moteur d'analyse JavaScript peuvent permettre aux attaquants d'exploiter ces failles lors de l'accès à des pages Web malveillantes, aboutissant à une exécution de code à distance et à la prise de contrôle du navigateur de la victime, voire de son système d'exploitation. Des recherches ont montré que les bugs du compilateur Clang C++ peuvent également entraîner des conséquences graves telles que l'exécution de code à distance.

Le compilateur Solidity ne fait pas exception, selon l'alerte de sécurité de l'équipe de développement de Solidity, plusieurs versions différentes du compilateur Solidity présentent des vulnérabilités de sécurité.

Vulnérabilité du compilateur Solidity

Le rôle du compilateur Solidity est de convertir le code des contrats intelligents écrit par les développeurs en code d'instructions pour la machine virtuelle Ethereum (EVM). Ces codes d'instructions EVM sont empaquetés et téléchargés sur Ethereum via des transactions, et sont finalement interprétés et exécutés par l'EVM.

Il est nécessaire de distinguer les vulnérabilités du compilateur Solidity des vulnérabilités de l'EVM elle-même. Les vulnérabilités de l'EVM font référence aux failles de sécurité qui surviennent lorsque la machine virtuelle exécute des instructions. Comme les attaquants peuvent télécharger n'importe quel code sur Ethereum, ce code sera finalement exécuté sur chaque programme client P2P d'Ethereum. Si l'EVM présente des vulnérabilités de sécurité, cela affectera l'ensemble du réseau Ethereum, pouvant entraîner une déni de service (DoS) et même permettre à un attaquant de prendre complètement le contrôle de la chaîne. Cependant, en raison de la conception relativement simple de l'EVM et du fait que le code de base n'est pas fréquemment mis à jour, la probabilité d'apparition de ces problèmes est relativement faible.

Les vulnérabilités du compilateur Solidity se réfèrent aux failles qui se produisent lorsque le compilateur convertit Solidity en code EVM. Contrairement à des scénarios où le JavaScript est compilé et exécuté sur l’ordinateur client de l’utilisateur, comme avec des navigateurs, le processus de compilation de Solidity se déroule uniquement sur l’ordinateur du développeur de contrat intelligent et n’est pas exécuté sur Ethereum. Par conséquent, les vulnérabilités du compilateur Solidity n’affectent pas directement le réseau Ethereum lui-même.

Une des principales dangers des vulnérabilités du compilateur Solidity est qu'elles peuvent entraîner une incohérence entre le code EVM généré et les attentes des développeurs de contrats intelligents. Étant donné que les contrats intelligents sur Ethereum impliquent généralement les actifs cryptographiques des utilisateurs, tout bug causé par le compilateur dans les contrats intelligents peut entraîner des pertes d'actifs pour les utilisateurs, avec de graves conséquences.

Les développeurs et les auditeurs de contrats peuvent se concentrer sur les problèmes de mise en œuvre logique du code de contrat, ainsi que sur des problèmes de sécurité au niveau de Solidity tels que la réentrance et les débordements d'entiers. Cependant, il est difficile de détecter les vulnérabilités du compilateur Solidity uniquement par un audit de la logique du code source du contrat. Une analyse combinée d'une version spécifique du compilateur et de modèles de code spécifiques est nécessaire pour déterminer si le contrat intelligent est affecté par des vulnérabilités du compilateur.

Analyse des vulnérabilités du compilateur Solidity et mesures de réponse

Exemple de vulnérabilité du compilateur Solidity

Les exemples suivants de plusieurs cas réels de vulnérabilités des compilateurs Solidity illustrent les formes spécifiques, les causes et les dangers des vulnérabilités des compilateurs Solidity.

SOL-2016-9 HighOrderByteCleanStorage

Cette vulnérabilité existe dans les versions antérieures du compilateur Solidity (\u003e=0.1.6 \u003c0.4.4).

Considérez le code suivant :

solidité contrat C { uint32 a = 0x12345678; uint16 b = 0x1234;

fonction f() publique { a = a + 1; }

fonction run() public view returns (uint16) { return b; } }

La variable de stockage b n'a pas été modifiée, donc la fonction run() devrait retourner la valeur par défaut 0. Cependant, dans le code généré par une version du compilateur contenant une vulnérabilité, run() renverra 1.

Sans comprendre la vulnérabilité du compilateur, il est difficile pour un développeur ordinaire de détecter les bugs présents dans le code ci-dessus par une simple révision de code. Le code ci-dessus n'est qu'un exemple simple, il ne causera donc pas de dommages particulièrement graves. Cependant, si la variable b est utilisée pour la vérification des permissions, la comptabilité des actifs, etc., cette incohérence par rapport aux attentes pourrait entraîner des conséquences très graves.

La raison des anomalies décrites ci-dessus est que l'EVM utilise une machine virtuelle à pile, chaque élément de la pile étant de taille 32 octets (, c'est-à-dire la taille d'une variable uint256 ). D'autre part, chaque slot de stockage sous-jacent (storage) a également une taille de 32 octets. Le langage Solidity supporte des types de données tels que uint32 et d'autres types de moins de 32 octets, et le compilateur, lors du traitement de ce type de variable, doit effectuer des opérations de nettoyage appropriées sur les bits de poids fort (clean up) pour garantir l'exactitude des données. Dans le cas mentionné, lorsque l'addition entraîne un débordement d'entier, le compilateur n'a pas correctement nettoyé les bits de poids fort du résultat, entraînant l'écriture d'un bit de 1 dans le stockage après le débordement, ce qui a finalement écrasé la variable a et a modifié la valeur de la variable b à 1.

SOL-2022-4 InlineAssemblyMemorySideEffects

Cette vulnérabilité existe dans les compilateurs des versions >=0.8.13 <0.8.15. Le compilateur Solidity, lors de la conversion du langage Solidity en code EVM, ne se contente pas d'une simple traduction. Il effectue également une analyse approfondie du flux de contrôle et des données, réalisant divers processus d'optimisation de compilation pour réduire la taille du code généré et optimiser la consommation de gas durant l'exécution. Ce type d'opération d'optimisation est courant dans les compilateurs de nombreux langages de haut niveau, mais en raison de la complexité des situations à prendre en compte, il est également susceptible de contenir des bogues ou des vulnérabilités de sécurité.

Considérez le code suivant :

solidité contrat C { fonction f() public pure returns (uint256) { assemblage { mstore(0, 0x42) } uint256 x; assemblage { x := mload(0) } return x; } }

La vulnérabilité du code ci-dessus provient des opérations d'optimisation de compilation. Dans certains cas, si le code de la fonction contient des instructions modifiant les données à l'emplacement mémoire 0, mais qu'aucune autre partie du code n'utilise ces données par la suite, il est alors possible de supprimer directement le code de modification de la mémoire 0, ce qui permet d'économiser du gaz sans affecter la logique du programme par la suite.

Cette stratégie d'optimisation n'est pas en soi problématique, mais dans l'implémentation concrète du code du compilateur Solidity, ce type d'optimisation n'est appliqué que dans un seul bloc assembly. Dans l'exemple de code ci-dessus, l'écriture et l'accès à la mémoire 0 se trouvent dans deux blocs assembly différents, tandis que le compilateur n'a analysé et optimisé que le bloc assembly séparé. Comme il n'y a aucune opération de lecture après l'écriture dans la mémoire 0 dans le premier bloc assembly, il conclut que cette instruction d'écriture est redondante et supprimera cette instruction, ce qui provoque un bug. Dans la version vulnérable, la fonction f( renverra la valeur 0, alors qu'en réalité, le code ci-dessus devrait renvoyer la valeur correcte 0x42.

) SOL-2022-6 AbiReencodingHeadOverflowWithStaticArrayCleanup

Cette vulnérabilité affecte les compilateurs de version >= 0.5.8 et < 0.8.16. Considérons le code suivant :

solidité contrat C { function f###bytes calldata data( external pure returns )bytes memory( { bytes4) mémoire a = [bytes4[1]data(]; return abi.encode)a(; } }

En temps normal, le code ci-dessus devrait retourner que la variable a est "aaaa". Mais dans la version vulnérable, il renverra une chaîne vide "".

La cause de cette vulnérabilité est que Solidity effectue une opération abi.encode sur les tableaux de type calldata, en nettoyant incorrectement certaines données, ce qui entraîne une modification de données adjacentes et provoque une incohérence des données après encodage et décodage.

Il convient de noter que Solidity effectue implicitement une abi.encode sur les paramètres lors des appels externes et de l'émission d'événements, de sorte que la probabilité d'apparition du code de vulnérabilité mentionné ci-dessus est plus élevée que ce que l'on pourrait penser.

Cette vulnérabilité a été adaptée en un sujet de blockchain pour la célèbre compétition de sécurité 0ctf 2022, montrant l'impact des vulnérabilités de compilateur sur les contrats intelligents dans des scénarios de développement réels.

![Analyse des vulnérabilités du compilateur Solidity et mesures de réponse])https://img-cdn.gateio.im/webp-social/moments-c97428f89ed62d5ad8551cdb2ba30867.webp(

Conseils de sécurité

Pour les menaces et les réponses aux vulnérabilités du compilateur Solidity, les recommandations suivantes peuvent être données :

Pour les développeurs :

  • Utilisez une version plus récente du compilateur Solidity. Bien que les nouvelles versions puissent introduire de nouveaux problèmes de sécurité, les problèmes de sécurité connus sont généralement moins nombreux que dans les anciennes versions.

  • Améliorer les cas de test unitaire. La plupart des bugs au niveau du compilateur entraînent des résultats d'exécution du code qui ne correspondent pas aux attentes. Ce type de problème est difficile à détecter par la révision de code, mais il est facile à exposer lors de la phase de test. Par conséquent, augmenter la couverture de code peut minimiser ce type de problème.

  • Évitez autant que possible d'utiliser l'assemblage en ligne, le décodage et l'encodeur abi pour des tableaux multidimensionnels et des structures complexes, et évitez d'utiliser aveuglément les nouvelles fonctionnalités du langage et les fonctionnalités expérimentales en l'absence de besoins clairs. La plupart des vulnérabilités sont liées à des opérations telles que l'assemblage en ligne et les encodeurs abi. Les bogues sont plus susceptibles de se produire lorsque le compilateur traite des caractéristiques complexes du langage. D'autre part, les développeurs peuvent également se tromper en utilisant de nouvelles fonctionnalités, ce qui entraîne des problèmes de sécurité.

Pour le personnel de sécurité :

  • Lors de l'audit de sécurité du code Solidity, ne négligez pas les risques de sécurité que le compilateur Solidity pourrait introduire. Dans la classification des faiblesses des contrats intelligents )SWC(, l'élément de vérification correspondant est SWC-102 : Version du compilateur obsolète.

  • Dans le processus de développement de la sécurité interne, incitez l'équipe de développement à mettre à jour la version du compilateur Solidity et envisagez d'introduire un contrôle automatique de la version du compilateur dans le processus CI/CD.

  • Mais il n'est pas nécessaire de s'inquiéter excessivement des vulnérabilités des compilateurs, la plupart des vulnérabilités des compilateurs ne se déclenchent que dans des modèles de code spécifiques. Les contrats compilés avec des versions vulnérables des compilateurs ne présentent pas nécessairement de risques de sécurité, il est nécessaire d'évaluer l'impact réel sur la sécurité en fonction de la situation spécifique du projet.

Quelques ressources pratiques :

  • Alertes de sécurité publiées régulièrement par l'équipe Solidity :

  • Liste des bugs mise à jour régulièrement dans le dépôt officiel de Solidity :

  • Liste des bugs des compilateurs de chaque version :

  • Sur Etherscan, sur la page Code du Contrat, l'icône de point d'exclamation en forme de triangle dans le coin supérieur droit peut indiquer des vulnérabilités de sécurité dans la version du compilateur actuelle.

Résumé

Cet article présente le concept de vulnérabilités des compilateurs Solidity, analyse les risques de sécurité potentiels qu'elles peuvent engendrer dans l'environnement de développement Ethereum, et fournit des conseils pratiques en matière de sécurité pour les développeurs et les professionnels de la sécurité. Bien que les vulnérabilités des compilateurs ne soient pas courantes, leurs impacts peuvent être graves, ce qui mérite l'attention des développeurs et des professionnels de la sécurité.

![Analyse des vulnérabilités du compilateur Solidity et mesures d'atténuation])https://img-cdn.gateio.im/webp-social/moments-84f5083d8748f2aab71fd92671d999a7.webp(

ETH0.1%
Voir l'original
Cette page peut inclure du contenu de tiers fourni à des fins d'information uniquement. Gate ne garantit ni l'exactitude ni la validité de ces contenus, n’endosse pas les opinions exprimées, et ne fournit aucun conseil financier ou professionnel à travers ces informations. Voir la section Avertissement pour plus de détails.
  • Récompense
  • 7
  • Reposter
  • Partager
Commentaire
0/400
fork_in_the_roadvip
· 07-19 10:48
Un compilateur peut aussi avoir des vulnérabilités ? Pourquoi s'inquiéter !
Voir l'originalRépondre0
gas_fee_therapistvip
· 07-19 08:57
Cette vulnérabilité est bien expliquée~
Voir l'originalRépondre0
GateUser-75ee51e7vip
· 07-18 18:19
Avoir un bug est toujours mieux que le mining.
Voir l'originalRépondre0
MetaverseHobovip
· 07-16 19:40
Le compilateur a aussi échoué ? Ça stresse un peu.
Voir l'originalRépondre0
DeepRabbitHolevip
· 07-16 19:39
Mince alors, tant de failles et on joue encore à la Position de verrouillée ?
Voir l'originalRépondre0
GasWastervip
· 07-16 19:37
Des failles dans le compilateur aussi ? yyds
Voir l'originalRépondre0
ForkTonguevip
· 07-16 19:23
Le vol d'argent par les cartes est la méthode la plus fiable.
Voir l'originalRépondre0
Trader les cryptos partout et à tout moment
qrCode
Scan pour télécharger Gate app
Communauté
Français (Afrique)
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)