Un bug de solidez en SP1 expuso el Prover Network de mainnet de Succinct a pruebas inválidas
Puntos clave
- •La falla de solidez estaba en el verificador nativo de Rust de SP1, que consultaba la etiqueta de tamaño de cada tensor sin confirmar que coincidiera con el contenido almacenado, por lo que un atacante con una etiqueta falsificada podía hacer que una prueba fabricada pasara la verificación.
- •Las versiones 6.0.0 a 6.8.0 de sp1_hypercube, sp1_prover y sp1_sdk estaban afectadas, con las pruebas Core y Compressed expuestas solo cuando se enviaban directamente al verificador nativo de Rust.
- •Las verificaciones Groth16 y Plonk, incluidos los verificadores de Solidity en cadena, no se vieron afectadas porque se basan en pruebas envueltas con formas fijas y nunca tocan el formato de tensor controlado por el provador.
- •Succinct publicó la corrección en la versión 6.8.1 el 24 de septiembre, 17 días antes del aviso del 11 de octubre, y la desplegó en el Prover Network de mainnet, por lo que sus usuarios no necesitan acción mientras que los operadores autoalojados que aceptan pruebas no confiables deben actualizar.
- •El investigador Vitalis Salis descubrió el bug y lo reportó a través del programa de bug bounty de Immunefi, sumándose a una serie de problemas de solidez en sistemas de pruebas divulgados este año.

Un bug de solidez de alta gravedad en SP1, el sistema de pruebas de conocimiento cero de Succinct, dejó abierto el Prover Network de mainnet de la propia empresa a pruebas inválidas. SP1 es una máquina virtual de conocimiento cero (zkVM), diseñada para permitir a los desarrolladores probar la ejecución correcta de programas sin volver a ejecutarlos, y la solidez —la garantía de que un verificador solo acepta pruebas de ejecuciones que realmente ocurrieron tal como se afirmaron— es la propiedad de la que depende cada aplicación construida sobre tales pruebas. Según un aviso de seguridad de GitHub publicado el 11 de octubre, el Prover Network fue el único despliegue del que Succinct tenía conocimiento que se vio afectado.
Registrado como GHSA-p7v2-jjv3-8p8f, el aviso indica que un provador malicioso podría enviar una prueba de una ejecución inválida y el verificador de la red la aceptaría. El Prover Network acepta pruebas de provadores de terceros, lo que significa que su verificador debe tratar cada envío como potencialmente hostil, lo que hacía que la falla fuera directamente relevante para su operación, ya que la verificación sólida es lo que distingue el trabajo genuino de los resultados fabricados.
La explotación se limitó a la ruta del verificador nativo de Rust
El bug solo podía explotarse cuando las pruebas se enviaban directamente al verificador nativo de Rust de SP1. Las pruebas Core y Compressed estaban expuestas en esa ruta.
Las verificaciones Groth16 y Plonk no se vieron afectadas, porque se basan en pruebas envueltas con formas fijas y nunca tocan el formato de tensor controlado por el provador que está en el centro del problema. Los verificadores de Solidity utilizados para la verificación en cadena de Plonk y Groth16 también estuvieron a salvo. Las aplicaciones que llaman a la función verify_sp1_proof para verificar pruebas Compressed estaban protegidas solo si la agregación de pruebas terminaba en una prueba Groth16 o Plonk.
Según el aviso, las versiones 6.0.0 a 6.8.0 de sp1_hypercube, sp1_prover y sp1_sdk están afectadas. Succinct publicó la corrección en la versión 6.8.1 el 24 de septiembre, 17 días antes de que el aviso se hiciera público, y posteriormente la desplegó en el Prover Network de mainnet, una secuencia que significó que una corrección funcional ya estaba disponible antes de que los detalles técnicos de la falla se hicieran públicos.
Las etiquetas de tensor no coincidentes no se verificaban
La falla estaba en el verificador nativo de Rust de SP1, el componente responsable de determinar si una prueba es válida.
SP1 almacena datos multidimensionales en estructuras llamadas Tensors. Un Tensor combina un búfer de valores almacenados con dimensiones declaradas que describen su forma, y ambas deben coincidir para una verificación sólida: el número de elementos almacenados debe ser igual al producto de las dimensiones declaradas.
Cada pieza de datos de prueba lleva una etiqueta que indica su tamaño, pero el verificador nunca confirmó que la etiqueta coincidiera con el contenido real, consultando únicamente la etiqueta. Por lo tanto, un atacante podía enviar datos con una etiqueta falsificada. Las distintas partes de la verificación leerían luego diferentes porciones del mismo búfer, lo que significaba que una prueba fabricada podía pasar.
La versión 6.8.1 introduce una verificación de longitud durante la deserialización. Cualquier tensor cuyo número de elementosados no sea igual al producto de sus dimensiones declaradas es rechazado.
Quién debe actualizar
Los usuarios que solicitan pruebas al Prover Network de mainnet no necesitan cambiar nada por su parte. Los operadores que ejecutan su propio verificador nativo de Rust y aceptan pruebas de provadores en los que no confían deben actualizar a la versión 6.8.1. Dado que el aviso de Succinct solo podía abarcar los despliegues que conocía, los operadores con instalaciones propias son quienes deben verificar si sus configuraciones entran en el rango afectado, tomando como referencia la lista de versiones impactadas del aviso.
Divulgación e incidentes relacionados
Vitalis Salis descubrió la falla y la reportó a través del programa de bug bounty de Immunefi, según el aviso.
La divulgación se suma a una serie de problemas de solidez en sistemas de pruebas reportados este año. Cryptopolitan cubrió previamente un bug de solidez en el shielded pool Orchard de Zcash y un exploit en Foom.Cash en el que un atacante falsificó pruebas zkSNARK debido a una configuración incorrecta del verificador.