ActualitésCryptoUne faille de solidité de SP1 a exposé le Prover Network de mainnet de Succinct à des preuves invalides

Une faille de solidité de SP1 a exposé le Prover Network de mainnet de Succinct à des preuves invalides

Auteur: Cryptopolitan·

Points clés

  • •La faille de solidité se situait dans le vérificateur Rust natif de SP1, qui se fiait à l'étiquette de taille de chaque tenseur sans confirmer qu'elle correspondait au contenu stocké, de sorte qu'un attaquant disposant d'une étiquette falsifiée pouvait faire passer une preuve fabriquée.
  • •Les versions 6.0.0 à 6.8.0 de sp1_hypercube, sp1_prover et sp1_sdk étaient affectées, les preuves Core et Compressed n'étant exposées que lorsqu'elles étaient envoyées directement au vérificateur Rust natif.
  • •Les vérifications Groth16 et Plonk, y compris les vérificateurs Solidity on-chain, n'étaient pas affectées car elles reposent sur des preuves enveloppées de forme fixe et ne touchent jamais le format tensoriel contrôlé par le prouver.
  • •Succinct a livré le correctif dans la version 6.8.1 le 24 septembre, soit 17 jours avant l'avis du 11 octobre, et l'a déployé sur le Prover Network de mainnet, ce qui signifie que ses utilisateurs n'ont rien à faire tandis que les opérateurs auto-hébergés acceptant des preuves non fiables doivent procéder à la mise à niveau.
  • •Le chercheur Vitalis Salis a découvert la faille et l'a signalée via le programme de bug bounty d'Immunefi, s'ajoutant à une série de problèmes de solidité de systèmes de preuve divulgués cette année.
Une faille de solidité de SP1 a exposé le Prover Network de mainnet de Succinct à des preuves invalides

Une faille de solidité de gravité élevée dans SP1, le système de preuve à connaissance zéro de Succinct, a laissé le Prover Network de mainnet de l'entreprise ouvert à des preuves invalides. SP1 est une machine virtuelle à connaissance zéro (zkVM), conçue pour permettre aux développeurs de prouver l'exécution correcte de programmes sans devoir les réexécuter, et la solidité — la garantie qu'un vérificateur n'accepte que des preuves d'exécutions réellement survenues comme prétendu — est la propriété dont dépend toute application construite sur de telles preuves. Selon un avis de sécurité GitHub publié le 11 octobre, le Prover Network était le seul déploiement affecté connu de Succinct.

Enregistré sous la référence GHSA-p7v2-jjv3-8p8f, l'avis indique qu'un prouver malveillant aurait pu soumettre une preuve pour une exécution invalide et que le vérificateur du réseau l'aurait acceptée. Le Prover Network accepte les preuves de prouvers tiers, ce qui signifie que son vérificateur doit traiter chaque soumission comme potentiellement hostile — ce qui rendait la faille directement pertinente pour son fonctionnement, puisque la vérification fiable est ce qui distingue le travail authentique des résultats fabriqués.

Une exploitation limitée à la voie du vérificateur Rust natif

La faille ne pouvait être exploitée que lorsque les preuves étaient envoyées directement au vérificateur Rust natif de SP1. Les preuves Core et Compressed étaient exposées sur cette voie.

Les vérifications Groth16 et Plonk n'étaient pas affectées, car elles reposent sur des preuves enveloppées de forme fixe et ne touchent jamais le format tensoriel contrôlé par le prouver au cœur du problème. Les vérificateurs Solidity utilisés pour la vérification on-chain Plonk et Groth16 étaient également sûrs. Les applications qui appellent la fonction verify_sp1_proof pour vérifier les preuves Compressed n'étaient protégées que si l'agrégation des preuves se terminait par une preuve Groth16 ou Plonk.

Selon l'avis, les versions 6.0.0 à 6.8.0 de sp1_hypercube, sp1_prover et sp1_sdk sont affectées. Succinct a livré le correctif dans la version 6.8.1 le 24 septembre, soit 17 jours avant que l'avis ne soit rendu public, et l'a ensuite déployé sur le Prover Network de mainnet — un séquençage qui signifiait qu'un correctif fonctionnel était déjà disponible avant que les détails techniques de la faille ne soient rendus publics.

Des étiquettes de tenseurs incohérentes non vérifiées

La faille se situait dans le vérificateur Rust natif de SP1, le composant chargé de déterminer si une preuve est valide.

SP1 stocke les données multidimensionnelles dans des structures appelées Tensors. Un Tensor combine un tampon de valeurs stockées avec des dimensions déclarées décrivant sa forme, et les deux doivent concorder pour une vérification fiable : le nombre d'éléments stockés doit être égal au produit des dimensions déclarées.

Chaque élément de données de preuve comporte une étiquette indiquant sa taille, mais le vérificateur n'a jamais confirmé que l'étiquette correspondait au contenu réel, se fiant uniquement à l'étiquette. Un attaquant pouvait donc soumettre des données portant une étiquette falsifiée. Différentes parties de la vérification lisaient alors différentes portions du même tampon, ce qui permettait à une preuve fabriquée de passer.

La version 6.8.1 introduit une vérification de longueur lors de la désérialisation. Tout tenseur dont le nombre déléments stockés n'est pas égal au produit de ses dimensions déclarées est rejeté.

Qui doit effectuer la mise à niveau

Les utilisateurs qui demandent des preuves au Prover Network de mainnet n'ont rien à changer de leur côté. Les opérateurs qui exécutent leur propre vérificateur Rust natif et acceptent des preuves de prouvers en qui ils n'ont pas confiance doivent passer à la version 6.8.1. Comme l'avis de Succinct ne pouvait rendre compte que des déploiements qu'il connaissait, ce sont les opérateurs auto-hébergés qui sont en mesure de vérifier si leur propre configuration se situe dans la plage affectée, la liste des versions impactées de l'avis servant de référence.

Divulgation et incidents connexes

Vitalis Salis a découvert la faille et l'a signalée via le programme de bug bounty d'Immunefi, selon l'avis.

Cette divulgation s'ajoute à une série de problèmes de solidité de systèmes de preuve signalés cette année. Cryptopolitan avait précédemment couvert une faille de solidité dans le pool protégé Orchard de Zcash et un exploit chez Foom.Cash dans lequel un attaquant avait forgé des preuves zkSNARK en raison d'une mauvaise configuration d'un vérificateur.