Analyse des vulnérabilités du compilateur Solidity et mesures d'atténuation
Le compilateur est l'un des composants fondamentaux des systèmes informatiques modernes, dont la fonction est de convertir le code source des langages de programmation de haut niveau en code d'instructions exécutable par l'ordinateur. Bien que les développeurs et les spécialistes de la sécurité se concentrent généralement sur la sécurité du code des applications, le compilateur lui-même, en tant que programme informatique, peut également présenter des vulnérabilités de sécurité, ce qui peut, dans certains cas, entraîner des risques de sécurité graves.
Par exemple, lorsque le navigateur compile et exécute du code JavaScript, il peut y avoir une exécution de code à distance due à une vulnérabilité du moteur d'analyse, permettant à un attaquant de prendre le contrôle du navigateur de la victime, voire de son système d'exploitation. Des recherches ont également montré que des bugs dans les compilateurs C++ peuvent également entraîner des exécutions de code à distance et d'autres conséquences graves.
Le compilateur Solidity présente également des vulnérabilités de sécurité. Selon l'alerte de sécurité de l'équipe de développement, des problèmes de sécurité ont été découverts dans plusieurs versions du compilateur Solidity.
Le rôle du compilateur Solidity est de convertir le code des contrats intelligents en code d'instructions pour la machine virtuelle Ethereum (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 se réfèrent aux problèmes de sécurité lors de l'exécution des instructions par la machine virtuelle, ce qui peut affecter l'ensemble du réseau Ethereum. En revanche, les vulnérabilités du compilateur Solidity concernent les problèmes survenant lors de la conversion de Solidity en code EVM, qui n'affectent pas directement le réseau Ethereum, mais peuvent entraîner une incohérence entre le code EVM généré et les attentes du développeur.
Étant donné que les contrats intelligents impliquent généralement des actifs cryptographiques des utilisateurs, tout bug causé par le compilateur peut avoir des conséquences graves. Il est difficile de détecter les vulnérabilités du compilateur uniquement en auditant le code source du contrat, une analyse combinée avec des versions spécifiques et des modèles de code est nécessaire.
Voici quelques cas réels qui illustrent les formes, les causes et les dangers des vulnérabilités du compilateur Solidity.
SOL-2016-9 HighOrderByteCleanStorage
Cette vulnérabilité existe dans les versions antérieures du compilateur Solidity (>=0.1.6 <0.4.4).
Considérez le code suivant :
solidité
contrat C {
uint32 a = 0x1234;
uint32 b = 0;
fonction f() publique {
a += 1;
}
fonction run() publique vue retourne (uint) {
return b;
}
}
La variable b n'ayant pas été modifiée, la fonction run() devrait retourner la valeur par défaut 0. Cependant, dans le code généré par la version vulnérable du compilateur, run() renvoie 1.
C'est parce que l'EVM utilise des éléments de pile de taille 32 octets, tandis que Solidity prend en charge des types inférieurs à 32 octets comme uint32. Le compilateur doit effectuer des opérations de nettoyage sur les bits supérieurs pour garantir l'exactitude des données. Lors d'un dépassement d'addition, le compilateur n'a pas correctement nettoyé les bits supérieurs, ce qui a conduit au bit de dépassement de 1 à être écrit dans le stockage, écrasant la variable b.
SOL-2022-4 Effets de côté de mémoire en InlineAssembly
Cette vulnérabilité existe dans les compilateurs des versions >=0.8.13 <0.8.15.
Considérez le code suivant :
solidité
contrat C {
fonction f() publique pure retourne (uint) {
assemblage {
mstore(0, 0x42)
}
uint x;
assemblage {
x := mload(0)
}
return x;
}
}
Le compilateur, lors du processus d'optimisation, analysera le flux de contrôle et le flux de données afin de réduire la taille du code et d'optimiser la consommation de gaz. Cependant, cette optimisation peut facilement entraîner des bugs.
Dans cet exemple, le compilateur considère à tort que l'écriture dans la mémoire 0 dans le premier bloc d'assemblage est redondante et l'élimine, ce qui entraîne un retour de la fonction f() à 0 au lieu du bon 0x42.
SOL-2022-6 Débordement de tête AbiReencoding avec nettoyage de tableau statique
Cette vulnérabilité affecte les compilateurs de la version >= 0.5.8 et < 0.8.16.
Considérez le code suivant :
solidité
contrat C {
fonction f(string[1] calldata a) public pure returns (string memory) {
return abi.decode(abi.encode(a), (string[1]))[0];
}
}
En temps normal, ce code devrait renvoyer la valeur de la variable a "aaaa". Mais dans la version vulnérable, il renverra une chaîne vide "".
C'est parce que Solidity a mal nettoyé certaines données lors de l'opération abi.encode sur les tableaux de type calldata, ce qui a entraîné la modification des données adjacentes, provoquant une incohérence des données après le codage et le décodage.
Il est important de noter que lors d'un appel externe et d'un événement émis, abi.encode est implicitement effectué, ce qui augmente la probabilité de l'apparition de ce type de vulnérabilité.
Conseils de sécurité
Pour les développeurs :
Utilisez une version plus récente du compilateur Solidity, les problèmes de sécurité connus sont généralement moins fréquents.
Améliorer les cas de test unitaires, augmenter la couverture du code, aide à découvrir les problèmes causés par le compilateur.
Évitez d'utiliser des assemblages en ligne, des opérations complexes de décodage et d'encodage ABI, et ne pas utiliser aveuglément de nouvelles fonctionnalités et des fonctions expérimentales.
Pour le personnel de sécurité:
Ne négligez pas les risques que le compilateur peut introduire lors de l'audit, correspondant à l'élément de vérification SWC-102.
Dans le processus SDL, promouvoir la mise à niveau de la version du compilateur et envisager d'introduire une vérification automatique.
Évaluer l'impact réel des vulnérabilités des compilateurs, sans trop de panique.
Quelques ressources utiles :
Blog d'alerte de sécurité officiel Solidity
Liste des bugs dans le dépôt Solidity
Liste des bugs des différents compilateurs
Alerte de vulnérabilité du compilateur sur la page de contrat d'Etherscan
En résumé, les vulnérabilités du compilateur Solidity peuvent entraîner un comportement réel des contrats intelligents qui ne correspond pas aux attentes. Les développeurs et les professionnels de la sécurité doivent rester vigilants et prendre des mesures appropriées pour réduire les risques.
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.
16 J'aime
Récompense
16
5
Reposter
Partager
Commentaire
0/400
ColdWalletGuardian
· 08-06 10:09
Encore osé utiliser un compilateur ancien, espèce de débile.
Voir l'originalRépondre0
LayerZeroHero
· 08-06 02:28
Le compilateur n'est pas très stable non plus.
Voir l'originalRépondre0
RektRecorder
· 08-03 12:34
C'est tellement dangereux, c'est fou fam
Voir l'originalRépondre0
BearMarketGardener
· 08-03 12:30
Le compilateur a aussi de nombreuses failles, en un clin d'œil, les actifs disparaissent.
Voir l'originalRépondre0
SnapshotBot
· 08-03 12:27
Le compilateur a encore un problème, il s'est échappé.
Analyse des vulnérabilités du compilateur Solidity : un risque de smart contracts à ne pas négliger
Analyse des vulnérabilités du compilateur Solidity et mesures d'atténuation
Le compilateur est l'un des composants fondamentaux des systèmes informatiques modernes, dont la fonction est de convertir le code source des langages de programmation de haut niveau en code d'instructions exécutable par l'ordinateur. Bien que les développeurs et les spécialistes de la sécurité se concentrent généralement sur la sécurité du code des applications, le compilateur lui-même, en tant que programme informatique, peut également présenter des vulnérabilités de sécurité, ce qui peut, dans certains cas, entraîner des risques de sécurité graves.
Par exemple, lorsque le navigateur compile et exécute du code JavaScript, il peut y avoir une exécution de code à distance due à une vulnérabilité du moteur d'analyse, permettant à un attaquant de prendre le contrôle du navigateur de la victime, voire de son système d'exploitation. Des recherches ont également montré que des bugs dans les compilateurs C++ peuvent également entraîner des exécutions de code à distance et d'autres conséquences graves.
Le compilateur Solidity présente également des vulnérabilités de sécurité. Selon l'alerte de sécurité de l'équipe de développement, des problèmes de sécurité ont été découverts dans plusieurs versions du compilateur Solidity.
Le rôle du compilateur Solidity est de convertir le code des contrats intelligents en code d'instructions pour la machine virtuelle Ethereum (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 se réfèrent aux problèmes de sécurité lors de l'exécution des instructions par la machine virtuelle, ce qui peut affecter l'ensemble du réseau Ethereum. En revanche, les vulnérabilités du compilateur Solidity concernent les problèmes survenant lors de la conversion de Solidity en code EVM, qui n'affectent pas directement le réseau Ethereum, mais peuvent entraîner une incohérence entre le code EVM généré et les attentes du développeur.
Étant donné que les contrats intelligents impliquent généralement des actifs cryptographiques des utilisateurs, tout bug causé par le compilateur peut avoir des conséquences graves. Il est difficile de détecter les vulnérabilités du compilateur uniquement en auditant le code source du contrat, une analyse combinée avec des versions spécifiques et des modèles de code est nécessaire.
Voici quelques cas réels qui illustrent les formes, les causes et les dangers des vulnérabilités du compilateur Solidity.
SOL-2016-9 HighOrderByteCleanStorage
Cette vulnérabilité existe dans les versions antérieures du compilateur Solidity (>=0.1.6 <0.4.4).
Considérez le code suivant :
solidité contrat C { uint32 a = 0x1234; uint32 b = 0; fonction f() publique { a += 1; } fonction run() publique vue retourne (uint) { return b; } }
La variable b n'ayant pas été modifiée, la fonction run() devrait retourner la valeur par défaut 0. Cependant, dans le code généré par la version vulnérable du compilateur, run() renvoie 1.
C'est parce que l'EVM utilise des éléments de pile de taille 32 octets, tandis que Solidity prend en charge des types inférieurs à 32 octets comme uint32. Le compilateur doit effectuer des opérations de nettoyage sur les bits supérieurs pour garantir l'exactitude des données. Lors d'un dépassement d'addition, le compilateur n'a pas correctement nettoyé les bits supérieurs, ce qui a conduit au bit de dépassement de 1 à être écrit dans le stockage, écrasant la variable b.
SOL-2022-4 Effets de côté de mémoire en InlineAssembly
Cette vulnérabilité existe dans les compilateurs des versions >=0.8.13 <0.8.15.
Considérez le code suivant :
solidité contrat C { fonction f() publique pure retourne (uint) { assemblage { mstore(0, 0x42) } uint x; assemblage { x := mload(0) } return x; } }
Le compilateur, lors du processus d'optimisation, analysera le flux de contrôle et le flux de données afin de réduire la taille du code et d'optimiser la consommation de gaz. Cependant, cette optimisation peut facilement entraîner des bugs.
Dans cet exemple, le compilateur considère à tort que l'écriture dans la mémoire 0 dans le premier bloc d'assemblage est redondante et l'élimine, ce qui entraîne un retour de la fonction f() à 0 au lieu du bon 0x42.
SOL-2022-6 Débordement de tête AbiReencoding avec nettoyage de tableau statique
Cette vulnérabilité affecte les compilateurs de la version >= 0.5.8 et < 0.8.16.
Considérez le code suivant :
solidité contrat C { fonction f(string[1] calldata a) public pure returns (string memory) { return abi.decode(abi.encode(a), (string[1]))[0]; } }
En temps normal, ce code devrait renvoyer la valeur de la variable a "aaaa". Mais dans la version vulnérable, il renverra une chaîne vide "".
C'est parce que Solidity a mal nettoyé certaines données lors de l'opération abi.encode sur les tableaux de type calldata, ce qui a entraîné la modification des données adjacentes, provoquant une incohérence des données après le codage et le décodage.
Il est important de noter que lors d'un appel externe et d'un événement émis, abi.encode est implicitement effectué, ce qui augmente la probabilité de l'apparition de ce type de vulnérabilité.
Conseils de sécurité
Pour les développeurs :
Pour le personnel de sécurité:
Quelques ressources utiles :
En résumé, les vulnérabilités du compilateur Solidity peuvent entraîner un comportement réel des contrats intelligents qui ne correspond pas aux attentes. Les développeurs et les professionnels de la sécurité doivent rester vigilants et prendre des mesures appropriées pour réduire les risques.