Wormhole Bridge Hack : Analyse technique de l'exploit à 326M$

Article author

Analyse technique de l’exploitation du hack du Wormhole Bridge à hauteur de 326 millions de dollars

Le 2 février 2022, le pont de tokens Wormhole a perdu 120 000 wETH — soit environ 326 millions de dollars à l’époque — dans ce qui reste l’un des plus grands exploits de smart contracts dans l’histoire de la DeFi. L’attaque ne nécessitait aucun vol de clés, aucune ingénierie sociale, ni contrôle majoritaire du réseau de validateurs Guardian. Elle n’a requis qu’une seule chose : une API de programme Solana obsolète qui ne vérifiait pas de quel compte elle lisait.

Comprendre cet exploit est essentiel pour chaque équipe construisant sur Solana, chaque protocole s’appuyant sur le messaging cross-chain et chaque auditeur passant en revue des programmes Solana. La cause racine était une faille de vérification de smart contract dans le programme pont Wormhole sur Solana — pas une compromission de clés, ni une défaillance du réseau Guardian. Les clés Guardian n’ont jamais été touchées. Le code même du pont a accordé à l’attaquant une autorisation qu’il n’aurait jamais dû lui accorder.

Quelle était la principale vulnérabilité technique dans le hack Wormhole ?

La vulnérabilité résidait dans l’instruction verify_signatures du programme pont Wormhole sur Solana (bridge.so). Cette fonction était responsable de vérifier qu’un compte SignatureSet — contenant des signatures Ed25519 ou Secp256k1 des nœuds Guardian — représentait un consensus authentique avant d’autoriser une Verifiable Action Approval (VAA).

La faille : verify_signatures utilisait la fonction obsolète solana_program::sysvar::instructions::load_instruction_at pour vérifier qu’une instruction de pré-vérification Secp256k1 avait été appelée plus tôt dans la même transaction. La variante dépréciée ne valide pas que le compte passé est bien le sysvar instructions de Solana (Sysvar1nstructions1111111111111111111111111). Elle lit depuis n’importe quel compte situé à l’index nommé — y compris un compte entièrement contrôlé par l’appelant.

Un attaquant peut donc fournir un compte falsifié qui imite la structure du sysvar instructions, pré-rempli avec des données de signature contrôlées par l’attaquant sur une charge utile choisie par celui-ci. La fonction lit ces fausses données, constate que l’appel Secp256k1 est “présent” (dans un contexte complètement différent), marque le VAA comme approuvé par Guardian, et retourne un succès.

Ayant en main un VAA approuvé frauduleusement, l’attaquant invoqua complete_wrapped, qui fait confiance à l’approbation du VAA du programme pont pour autoriser la création de tokens wrapped sur Solana. Résultat : 120 000 wETH ont été créés sans qu’aucun ETH correspondant ne soit bloqué sur Ethereum.

Un correctif — remplaçant load_instruction_at par load_instruction_at_checked, qui oblige à ce que le compte soit bien le sysvar instructions — avait été commité dans le dépôt GitHub de Wormhole avant l’exploit mais n’avait pas encore été déployé en mainnet.

Facteur Description Impact
API sysvar obsolète load_instruction_at sans variante _checked ; aucune vérification de propriétaire sur le compte passé à l’index nommé L’attaquant peut fournir un compte d’instruction forgé à la place du vrai sysvar instructions
Bypass de verify_signatures La fonction acceptait un SignatureSet fabriqué par l’attaquant comme preuve du consensus Guardian sans valider la provenance du compte Autorisation de mint accordée sans signatures Guardian réelles
Vérification manquante du propriétaire du compte Le compte SignatureSet n’était pas validé comme appartenant au programme sysvar instructions (Sysvar1nstructions11...) Cette absence est le fondement complet de l’exploit
Autorité de mint des tokens wrapped Le programme pont Solana détenait une autorité illimitée pour créer des tokens wrapped ; l’autorisation requérait uniquement un VAA marqué comme approuvé 120 000 wETH créés sur Solana sans ETH verrouillé sur Ethereum ; ~326M$ de valeur au moment de l’attaque

En quoi l’exploitation Wormhole diffère-t-elle des autres attaques de ponts telles que Ronin ?

Le hack du pont Ronin (mars 2022, ~625M$) est souvent cité avec Wormhole dans les discussions sur les failles de sécurité des ponts. Ce sont des modes d’échec fondamentalement différents.

Wormhole était un bug de vérification dans le smart contract du programme pont Solana. Le réseau Guardian — un schéma de signatures à seuil de 19 nœuds — n’a jamais été compromis. L’attaquant l’a complètement contourné en exploitant le fait que verify_signatures ne vérifiait jamais quel compte il lisait. Les clés Guardian étaient intactes, le réseau fonctionnait, mais cela était sans importance : le code ne consultait jamais le vrai consensus Guardian.

Ronin était un vol de clés opérationnel. Sky Mavis exploitait cinq des neuf nœuds validateurs Ronin. En novembre 2021, Axie DAO avait temporairement délégué l’autorité de signature à Sky Mavis pour gérer la charge des transactions. Cette délégation n’a jamais été révoquée à expiration. Un attaquant — attribué plus tard au groupe Lazarus — a compromis les systèmes internes de Sky Mavis et obtenu quatre clés validatrices. Usant de la délégation active de l’Axie DAO, il a acquis la cinquième signature via le nœud RPC sans gas de Sky Mavis. Avec cinq signatures valides sur neuf, ils ont soumis des messages de retrait légitimes au contrat pont Ronin. Aucun bug de smart contract n’a été exploité. Le pont a parfaitement fonctionné comme prévu avec cinq signatures validées — il a autorisé les retraits.

Wormhole (Fév 2022) Ronin (Mar 2022)
Vecteur d’attaque Contournement de vérification de compte programme Solana Ingénierie sociale et compromission d’identifiants des nœuds Sky Mavis
Méthode d’exploitation Compte SignatureSet forgé via API sysvar obsolète Retraits signés légitimes avec clés de validateurs volées
Réseau Guardian / validateurs Intact ; contourné par le code, non par l’attaquant Compromis — l’attaquant détenait 5 clés sur 9
Mode d’impact Mint non autorisé sur Solana sans ETH verrouillé sur Ethereum Retrait direct du contrat pont Ronin via signatures valides
Montant volé ~326M$ (120 000 wETH) ~625M$ (173 600 ETH + 25,5M USDC)
Leçon sécurité Validation de propriété de compte indispensable dans les programmes Solana ; schémas à seuil ne valent que si le pont les lit réellement Les schémas de signature à seuil ne protègent pas contre la compromission de clés majoritaires ; la révocation des délégations doit être assurée

Étape par étape : comment l’exploit Wormhole s’est déroulé

  1. Usurpation de compte. L’attaquant a créé un compte Solana imitant la structure attendue pour le SignatureSet dans les données d’instruction du programme pont Wormhole. Ce compte contenait des signatures contrôlées par l’attaquant — valides Ed25519/Secp256k1, mais sur une charge VAA choisie par l’attaquant autorisant un mint de 120 000 wETH à son adresse Solana.

  2. Bypass via API sysvar obsolète. L’attaquant a soumis une transaction appelant verify_signatures dans le programme pont Wormhole. Le programme invoquait load_instruction_at — la variante obsolète non vérifiée — pour confirmer qu’une instruction Secp256k1 avait été appelée plus tôt dans la même transaction. load_instruction_at lit depuis n’importe quel compte à l’index nommé sans vérifier qu’il s’agit du vrai sysvar instructions.

  3. Preuve forgée acceptée. verify_signatures parcourait les signatures dans le compte contrôlé par l’attaquant, les trouvait cryptographiquement valides (l’attaquant les avait signées lui-même, sur sa propre charge), et marquait le VAA comme approuvé par Guardian. Le réseau Guardian n’a jamais été consulté.

  4. Mint autorisé. L’attaquant invoqua complete_wrapped avec le VAA maintenant approuvé. Le programme pont, se fiant à ce statut d’approbation, a créé 120 000 wETH sur Solana à l’adresse de l’attaquant.

  5. Extraction cross-chain. L’attaquant a déplacé les wETH mintés vers Ethereum via le flux cross-chain légitime de Wormhole — les wETH existaient dans son wallet Solana, donc le pont traitait le retrait comme un transfert normal. Les 326M$ en wETH non adossés ont atterri sur Ethereum, où l’attaquant les a convertis en ETH et stablecoins puis sorti les fonds. Jump Crypto, la société mère de Wormhole, a reconstitué les 120 000 ETH volés à partir de ses propres réserves pour compenser les utilisateurs du pont.

Les leçons techniques les plus critiques pour les programmes Solana et les ponts cross-chain

1. Chaque AccountInfo passé à un programme Solana est contrôlé par l’attaquant jusqu’à preuve du contraire.

C’est la règle fondamentale de la sécurité des programmes Solana. Un programme doit valider les champs owner, key et — si applicable — executable et is_signer de chaque compte reçu. La fonction dépréciée load_instruction_at acceptait n’importe quel compte placé à l’index nommé. Son remplaçant moderne, load_instruction_at_checked, force à ce que le compte soit bien le sysvar instructions avant lecture. La méthodologie d’audit Solana de Soken identifie toute utilisation d’API sysvar non-_checked comme une découverte critique, quel que soit le contexte.

2. Séparation des privilèges entre la vérification des signatures et le mint de l’actif.

L’autorité de mint d’un pont doit être située derrière un module de vérification qui dérive la preuve d’un état canonique possédé par le programme — pas d’un compte passé par l’appelant. Quand verify_signatures acceptait un compte contrôlé par l’attaquant comme source de vérité, la séparation entre « le réseau a-t-il approuvé ? » et « pouvons-nous minter ? » s’effondrait complètement. L’instruction de mint doit dériver son autorisation d’un état validé par le programme lui-même après vérification de l’entrée Guardian réelle.

3. La protection contre la relecture des VAA doit être appliquée on-chain.

Même si le SignatureSet avait été authentique, complete_wrapped aurait dû rejeter les VAA dont le hash avait déjà été consommé. Wormhole a ajouté la protection contre la relecture dans les versions ultérieures, mais son absence dans la version exploitée signifiait qu’un VAA approuvé frauduleusement pouvait être réutilisé à l’infini. Chaque action d’un pont doit être conditionnée par une table de VAA consommés (processed_vaas : mapping[bytes32, bool]), mise à jour atomiquement au début de l’exécution.

4. L’usage d’API dépréciées est une découverte critique en audit.

La vulnérabilité Wormhole était un problème connu lié à une dépréciation. Le SDK Solana avait signalé load_instruction_at comme obsolète et proposé le remplacement _checked avant l’exploit. Ne pas migrer une API dépréciée n’est pas seulement un problème de qualité de code — c’est une faille critique que les attaquants recherchent activement en consultant les changelogs et en comparant les commits non déployés avec le bytecode déployé. Les audits de programmes Solana doivent scruter solana_program::sysvar::instructions::* à la recherche de variantes non-_checked et leur faire échouer la validation. C’est la pratique standard des audits Solana post-2022 chez Ottersec, Halborn et Soken.

5. Les correctifs de sécurité non déployés sont des cartes d’attaque publiques.

Le correctif load_instruction_at_checked avait été commité publiquement avant le hack. Un attaquant sophistiqué qui surveille les dépôts des protocoles cibles pour les commits de sécurité — notamment ceux remplaçant les API dépréciées — peut reconstruire la vulnérabilité à partir du diff seul. Les pipelines de déploiement de programmes critiques doivent considérer la période entre « fusionné en main » et « déployé en mainnet » comme une fenêtre d’exposition active. Les procédures de déploiement d’urgence doivent la fermer en heures, pas en jours.

6. Une multisignature à seuil ne compense pas un échec de validation des comptes.

Le réseau Guardian de Wormhole comprenait 19 nœuds indépendants fonctionnant sur un schéma de signatures à seuil. Il était robuste. Mais totalement hors sujet dans cette attaque. L’exploit a contourné toute la couche consensus en manipulant quel compte verify_signatures lisait. Les signatures à seuil protègent contre la compromission de clés Guardian ; elles ne protègent pas du tout contre un bug qui ne consulte jamais les Guardians. Une stratégie de défense en profondeur exige que chaque couche de sécurité soit réellement invoquée — un contrôle contourné n’est pas un contrôle du tout.

Ce que cela signifie pour les audits de ponts et la sécurité des programmes Solana

L’exploit Wormhole démontre que la sécurité d’un pont cross-chain est un problème multi-couches. Le réseau Guardian peut être cryptographiquement sain, les incitations économiques bien alignées, et l’architecture du protocole bien conçue — et un simple appel à une fonction obsolète dans le programme on-chain peut rendre tout cela inutile.

Pour les équipes construisant sur Solana, la leçon de validation de comptes se généralise : considérez chaque paramètre passé à votre programme comme malveillant. Validez propriétaire, clé, discriminateur et longueur des données avant toute manipulation de compte. Utilisez le wrapper Account<T> du framework anchor ou équivalent pour appliquer ces contrôles au niveau des types plutôt que par assertion manuelle.

Pour les architectes de ponts, la leçon est la séparation des privilèges et l’ancrage à un état canonique. L’autorité de mint doit retracer à un état possédé par le programme que celui-ci a validé — pas à des preuves fournies par l’appelant que le programme accepte sans vérification.

Soken audite chaque programme Solana pour l’usage d’API sysvar dépréciées, les manques de vérification de propriété de compte et les lacunes dans la protection contre la relecture des VAA comme des éléments critiques. Le schéma d’attaque Wormhole — contournement d’une multisig à seuil en manipulant le compte lu par une fonction de vérification — est désormais une classe d’attaque nommée dans notre méthodologie d’audit Solana. Si votre protocole utilise le messaging cross-chain ou le mint de tokens wrapped, contactez-nous sur soken.dev/services-it.html pour discuter d’une revue de sécurité avant déploiement.

Article author

Frequently Asked Questions

Quelle a été la cause principale du hack du Wormhole bridge ?

Une API Solana dépréciée (`load_instruction_at` sans `_checked`) dans la fonction `verify_signatures` ne vérifiait pas que l'account lu était le vrai sysvar des instructions. L'attaquant a passé un compte fabriqué avec signatures auto-signées, que la fonction a acceptées comme consensus Guardian, permettant la création de 120 000 wETH sur Solana sans verrouillage correspondant sur Ethereum.

Les clés validateurs Wormhole Guardian ont-elles été compromises ?

Non. Le système de signature à seuil sur 19 nœuds du réseau Guardian n'a jamais été violé. L'exploit a contourné cela en manipulant le compte lu par `verify_signatures` — le contrat n'a jamais consulté les Guardians réellement.

En quoi le hack Wormhole diffère-t-il du hack du bridge Ronin ?

Wormhole était un bug de vérification de smart contract sur Solana — aucune clé volée. Ronin impliquait un vol de clés opérationnelles — les attaquants ont obtenu cinq des neuf clés validateurs Sky Mavis via ingénierie sociale et délégation non révoquée Axie DAO, puis soumis des messages de retrait légitimes signés.

Comment les programmes Solana peuvent-ils prévenir ce type d'attaque ?

Valider chaque paramètre AccountInfo : vérifier owner, key, flags exécutables avant usage. Utiliser `load_instruction_at_checked` (ou wrapper Anchor Account) qui impose la propriété sysvar au niveau du type. Considérer tout appel sysvar sans `_checked` comme un problème critique à auditer.

Quelles pratiques d'audit permettent aujourd'hui de détecter ce problème ?

Les audits modernes scrutent l'usage des API `solana_program::sysvar::instructions::*` pour détecter les variantes sans `_checked` et échouent le contrôle en cas de détection. Ils vérifient aussi la protection contre rejouage des VAA, la séparation claire des privilèges entre vérification de preuve et autorisation de mint, ainsi que le déploiement rapide de correctifs de sécurité.

Chat