SP1-soundnessbug stelde het mainnet Prover Network van Succinct bloot aan ongeldige proofs
Belangrijkste punten
- •De soundness-fout zat in SP1's native Rust-verifieerder, die naar het grootte-label van elke tensor keek zonder te bevestigen dat dit overeenkwam met de opgeslagen inhoud, waardoor een aanvaller met een vervalst label een verzonnen proof kon laten slagen.
- •Versies 6.0.0 tot en met 6.8.0 van sp1_hypercube, sp1_prover en sp1_sdk waren getroffen, waarbij Core- en Compressed-proofs alleen waren blootgesteld wanneer ze rechtstreeks naar de native Rust-verifieerder werden gestuurd.
- •Groth16- en Plonk-controles, inclusief de on-chain Solidity-checkers, waren niet getroffen omdat ze vertrouwen op gewikkelde proofs met vaste vormen en nooit het door de prover gecontroleerde tensor-formaat aanraken.
- •Succinct bracht de fix uit in versie 6.8.1 op 24 september, 17 vóór de advisory van 11 oktober, en zette deze uit op het mainnet Prover Network, wat betekent dat gebruikers niets hoeven te doen terwijl zelfstandig draaiende beheerders die proofs van onbetrouwbare bronnen accepteren moeten upgraden.
- •Onderzoeker Vitalis Salis ontdekte de bug en meldde deze via het bug bounty-programma van Immunefi, waarmee het deel uitmaakt van een reeks soundness-problemen in proofsystemen die dit jaar zijn onthuld.

Een hoog-ernst soundness-bug in SP1, Succinct's zero-knowledge proofsysteem, liet het eigen mainnet Prover Network van het bedrijf openstaan voor ongeldige proofs. SP1 is een zero-knowledge virtuele machine (zkVM), ontworpen om ontwikkelaars te laten bewijzen dat programma's correct zijn uitgevoerd zonder ze opnieuw uit te voeren, en soundness — de garantie dat een verifieerder alleen proofs accepteert van executies die daadwerkelijk hebben plaatsgevonden zoals beweerd — is de eigenschap waar elke toepassing op dergelijke proofs van afhankelijk is. Volgens een GitHub security advisory die op 11 oktober werd gepubliceerd, was het Prover Network de enige implementatie waarvan Succinct wist dat deze was getroffen.
De advisory, geregistreerd als GHSA-p7v2-jjv3-8p8f, stelt dat een kwaadwillende prover een proof voor een ongeldige executie kon indienen en dat de verifieerder van het netwerk deze zou accepteren. Het Prover Network accepteert proofs van derde partijen, wat betekent dat de verifieerder elke inzending als potentieel vijandig moet behandelen — wat het lek direct relevant maakte voor de werking ervan, aangezien sounde verificatie is wat echt werk onderscheidt van verzonnen resultaten.
Misbruik beperkt tot het pad van de native Rust-verifieerder
De bug kon alleen worden misbruikt wanneer proofs rechtstreeks naar SP1's native Rust-verifieerder werden gestuurd. Core- en Compressed-proofs waren op dat pad blootgesteld.
Groth16- en Plonk-controles waren niet getroffen, omdat ze vertrouwen op gewikkelde proofs met vaste vormen en nooit het door de prover gecontroleerde tensor-formaat aanraken dat centraal staat in het probleem. De Solidity-checkers die worden gebruikt voor on-chain Plonk- en Groth16-verificatie waren ook veilig. Toepassingen die de functie verify_sp1_proof aanroepen om Compressed-proofs te verifiëren, waren alleen beschermd als proof-aggregatie eindigde in een Groth16- of Plonk-proof.
Volgens de advisory zijn versies 6.0.0 tot en met 6.8.0 van sp1_hypercube, sp1_prover en sp1_sdk getroffen. Succinct bracht de fix uit in versie 6.8.1 op 24 september, dagen voordat de advisory openbaar werd, en zette deze vervolgens uit op het mainnet Prover Network — een volgorde die betekende dat er een werkende fix beschikbaar was voordat de technische details van het lek openbaar werden.
Niet-overeenkomende tensor-labels bleven ongecontroleerd
Het lek zat in SP1's native Rust-verifieerder, het onderdeel dat verantwoordelijk is voor het bepalen of een proof geldig is.
SP1 slaat multidimensionale gegevens op in structuren die Tensors worden genoemd. Een Tensor combineert een buffer van opgeslagen waarden met gedeclareerde dimensies die de vorm beschrijven, en beide moeten overeenkomen voor een sounde verificatie: het aantal opgeslagen elementen moet gelijk zijn aan het product van de gedeclareerde dimensies.
Elk stuk proof-gegevens draagt een label dat de grootte aangeeft, maar de verifieerder heeft nooit bevestigd dat het label overeenkwam met de werkelijke inhoud; het keek alleen naar het label. Een aanvaller kon daarom gegevens indienen met een vervalst label. Verschillende delen van de controle lazen vervolgens verschillende gedeelten van dezelfde buffer, waardoor een verzonnen proof kon slagen.
Versie 6.8.1 introduceert een lengtecontrole tijdens deserialisatie. Elke tensor waarvan het aantal opgeslagen elementen niet gelijk is aan het product van de gedeclareerde dimensies wordt afgewezen.
Wie moet upgraden
Gebruikers die proofs aanvragen bij het mainnet Prover Network hoeven niets aan hun kant te wijzigen. Beheerders die hun eigen native Rust-verifieerder draaien en proofs accepteren van provers die ze niet vertrouwen, moeten upgraden naar 6.8.1. Omdat de advisory van Succinct alleen rekening kon houden met de implementaties die het bedrijf kende, zijn zelfstandig draaiende beheerders degene die moeten controleren of hun eigen opstellingen binnen het getroffen bereik vallen, met de lijst van getroffen releases uit de advisory als referentie.
Openbaarmaking en gerelateerde incidenten
Vitalis Salis ontdekte het lek en meldde het via het bug bounty-programma van Immunefi, aldus de advisory.
De openbaarmaking voegt zich bij een reeks soundness-problemen in proofsystemen die dit jaar zijn gemeld. Cryptopolitan berichtte eerder over een soundness-bug in Zcash's Orchard shielded pool en een exploit bij Foom.Cash waarbij een aanvaller zkSNARK-proofs vervalste vanwege een verkeerde configuratie van de verifieerder.