Le rapport d’incident de Scroll ce soir est bien plus intéressant que ces quatre mots : « n’a pas été exploité ».
Je suis allé consulter le message original sur le forum (11/11 14:24 UTC). Le problème concernait le contrat de vérification des preuves du bundle du mainnet, ZkEvmVerifierPostFeynman (0x7966…B254). Il assemblait manuellement les entrées et utilisait un raw staticcall pour appeler le vérificateur Halo2 d’OpenVM 2.0, en prenant directement les 4 premiers octets de l’appel dans la preuve fournie par le soumissionnaire. Or OpenVM 2.0 possède justement une fonction verify typée dont le selector est 0x24270d54. Si la preuve commençait par ces 4 octets, l’appel ne passait pas par le fallback, mais entrait dans cette fonction, qui lisait les entrées publiques à un emplacement contrôlé par l’appelant. Résultat : une ancienne preuve valide pouvait servir à certifier une nouvelle racine d’état et une nouvelle racine de retrait. En clair, on aurait théoriquement pu faire valider une racine de retrait entièrement fabriquée de toutes pièces : les fonds du bridge étaient dans le viseur.
L’ironie, c’est que ce contrat a été déployé lors de la mise à niveau vers OpenVM v2.0, le 22 septembre. L’annonce indiquait que l’une des raisons de cette mise à niveau était de corriger l’avis de sécurité de la v1.7.0, dont l’un des points s’intitulait « OpenVmHalo2Verifier self-call can bypass proof verification » : il s’agissait également d’un contournement au niveau du wrapper du vérificateur. Cette mise à niveau avait alors été qualifiée de maintenance ; seule une annonce avait été publiée, sans vote. Après avoir corrigé une faille dans le wrapper, le nouveau contrat en a introduit une autre au même niveau, qui est restée en place pendant 49 jours (du 22/09 au 10/11).
Pourquoi n’y a-t-il pas eu d’incident ? Le rapport l’explique : l’exploitation nécessitait le rôle de prouveur autorisé, ou bien le mode de lots forcés, qui n’est activé qu’après 7 jours sans confirmation finale. Pendant que le contrat vulnérable était en ligne, les 748 confirmations finales reposaient toutes sur des preuves normales ; le mode forcé n’a jamais été activé.
Ainsi, pendant ces 49 jours, ce qui a réellement servi de filet de sécurité, ce ne sont pas les mathématiques ZK, mais le fait que « seul le prouveur de Scroll pouvait soumettre des preuves ». On critique souvent la centralisation des prouveurs des L2 ; cette fois, c’est précisément la centralisation qui a gardé la porte fermée. Et le plus inquiétant, c’est l’envers du décor : le sas de secours de 7 jours, conçu pour résister à la censure, aurait, une fois déclenché, constitué une porte d’entrée pour une attaque ouverte à tous.
Je salue la divulgation. Le white hat ZHOUCHUNGONG a signalé le problème le 3/11, le contrat de correctif a été enregistré le 10/11 ; la nouvelle adresse, la PR du correctif et la transaction d’enregistrement ont toutes été publiées, avec des étapes permettant à chacun de vérifier les faits. C’est mieux que ce que font beaucoup de projets. Mais cette idée selon laquelle « avec une validity proof, il n’est pas nécessaire de faire confiance à l’opérateur » vient d’être démontée par le propre rapport du projet. Si vous détenez des actifs sur une L2, ne vous contentez pas de demander si elle utilise le ZK : demandez qui fait tourner le prouveur, à quelle fréquence le contrat de vérification est remplacé, et s’il y a un vote et un audit lors de son remplacement. Le montant de la prime et l’existence éventuelle d’un audit externe du nouveau contrat ne sont pas indiqués dans le rapport ; je ne vais pas spéculer.
#Scroll #以太坊L2
Je suis allé consulter le message original sur le forum (11/11 14:24 UTC). Le problème concernait le contrat de vérification des preuves du bundle du mainnet, ZkEvmVerifierPostFeynman (0x7966…B254). Il assemblait manuellement les entrées et utilisait un raw staticcall pour appeler le vérificateur Halo2 d’OpenVM 2.0, en prenant directement les 4 premiers octets de l’appel dans la preuve fournie par le soumissionnaire. Or OpenVM 2.0 possède justement une fonction verify typée dont le selector est 0x24270d54. Si la preuve commençait par ces 4 octets, l’appel ne passait pas par le fallback, mais entrait dans cette fonction, qui lisait les entrées publiques à un emplacement contrôlé par l’appelant. Résultat : une ancienne preuve valide pouvait servir à certifier une nouvelle racine d’état et une nouvelle racine de retrait. En clair, on aurait théoriquement pu faire valider une racine de retrait entièrement fabriquée de toutes pièces : les fonds du bridge étaient dans le viseur.
L’ironie, c’est que ce contrat a été déployé lors de la mise à niveau vers OpenVM v2.0, le 22 septembre. L’annonce indiquait que l’une des raisons de cette mise à niveau était de corriger l’avis de sécurité de la v1.7.0, dont l’un des points s’intitulait « OpenVmHalo2Verifier self-call can bypass proof verification » : il s’agissait également d’un contournement au niveau du wrapper du vérificateur. Cette mise à niveau avait alors été qualifiée de maintenance ; seule une annonce avait été publiée, sans vote. Après avoir corrigé une faille dans le wrapper, le nouveau contrat en a introduit une autre au même niveau, qui est restée en place pendant 49 jours (du 22/09 au 10/11).
Pourquoi n’y a-t-il pas eu d’incident ? Le rapport l’explique : l’exploitation nécessitait le rôle de prouveur autorisé, ou bien le mode de lots forcés, qui n’est activé qu’après 7 jours sans confirmation finale. Pendant que le contrat vulnérable était en ligne, les 748 confirmations finales reposaient toutes sur des preuves normales ; le mode forcé n’a jamais été activé.
Ainsi, pendant ces 49 jours, ce qui a réellement servi de filet de sécurité, ce ne sont pas les mathématiques ZK, mais le fait que « seul le prouveur de Scroll pouvait soumettre des preuves ». On critique souvent la centralisation des prouveurs des L2 ; cette fois, c’est précisément la centralisation qui a gardé la porte fermée. Et le plus inquiétant, c’est l’envers du décor : le sas de secours de 7 jours, conçu pour résister à la censure, aurait, une fois déclenché, constitué une porte d’entrée pour une attaque ouverte à tous.
Je salue la divulgation. Le white hat ZHOUCHUNGONG a signalé le problème le 3/11, le contrat de correctif a été enregistré le 10/11 ; la nouvelle adresse, la PR du correctif et la transaction d’enregistrement ont toutes été publiées, avec des étapes permettant à chacun de vérifier les faits. C’est mieux que ce que font beaucoup de projets. Mais cette idée selon laquelle « avec une validity proof, il n’est pas nécessaire de faire confiance à l’opérateur » vient d’être démontée par le propre rapport du projet. Si vous détenez des actifs sur une L2, ne vous contentez pas de demander si elle utilise le ZK : demandez qui fait tourner le prouveur, à quelle fréquence le contrat de vérification est remplacé, et s’il y a un vote et un audit lors de son remplacement. Le montant de la prime et l’existence éventuelle d’un audit externe du nouveau contrat ne sont pas indiqués dans le rapport ; je ne vais pas spéculer.
#Scroll #以太坊L2