NewsCryptoSP1 Soundness Bug Exposed Succinct's Mainnet Prover Network to Invalid Proofs

SP1 Soundness Bug Exposed Succinct's Mainnet Prover Network to Invalid Proofs

Author: Cryptopolitan·

Key Takeaways

  • •The soundness flaw sat in SP1's native Rust verifier, which consulted each tensor's size label without confirming it matched the stored contents, so an attacker with a falsified label could make a fabricated proof pass verification.
  • •Versions 6.0.0 through 6.8.0 of sp1_hypercube, sp1_prover, and sp1_sdk were affected, with Core and Compressed proofs exposed only when sent directly to the native Rust verifier.
  • •Groth16 and Plonk checks, including the on-chain Solidity checkers, were unaffected because they rely on wrapped proofs with fixed shapes and never touch the prover-controlled tensor format.
  • •Succinct shipped the fix in version 6.8.1 on Sept. 24, 17 days before the Oct. 11 advisory, and deployed it to the mainnet Prover Network, meaning its users need no action while self-hosted operators accepting untrusted proofs must upgrade.
  • •Researcher Vitalis Salis discovered the bug and reported it through Immunefi's bug bounty program, adding to a series of proof-system soundness issues disclosed this year.
SP1 Soundness Bug Exposed Succinct's Mainnet Prover Network to Invalid Proofs

A high-severity soundness bug in SP1, Succinct's zero-knowledge proving system, left the company's own mainnet Prover Network open to invalid proofs. SP1 is a zero-knowledge virtual machine (zkVM), designed to let developers prove the correct execution of programs without re-running them, and soundness — the guarantee that a verifier accepts only proofs of executions that actually occurred as claimed — is the property every application built on such proofs depends on. According to a GitHub security advisory released Oct. 11, the Prover Network was the only deployment Succinct was aware of that was affected.

Filed as GHSA-p7v2-jjv3-8p8f, the advisory states that a malicious prover could submit a proof for an invalid execution and the network's verifier would accept it. The Prover Network accepts proofs from third-party provers, meaning its verifier has to treat every submission as potentially hostile — which made the flaw directly relevant to its operation, since sound verification is what separates genuine work from fabricated results.

Exploitation limited to the native Rust verifier path

The bug could only be exploited when proofs were sent directly to SP1's native Rust verifier. Core and Compressed proofs were exposed on that path.

Groth16 and Plonk checks were unaffected, because they rely on wrapped proofs with fixed shapes and never touch the prover-controlled tensor format at the center of the issue. The Solidity checkers used for on-chain Plonk and Groth16 verification were also safe. Applications that call the verify_sp1_proof function to verify Compressed proofs were protected only if proof aggregation ended in a Groth16 or Plonk proof.

According to the advisory, versions 6.0.0 through 6.8.0 of sp1_hypercube, sp1_prover, and sp1_sdk are affected. Succinct shipped the fix in version 6.8.1 on Sept. 24, 17 days before the advisory was made public, and subsequently deployed it to the mainnet Prover Network — a sequencing that meant a working fix was already available before the technical details of the flaw became public.

Mismatched tensor labels went unchecked

The flaw sat in SP1's native Rust verifier, the component responsible for determining whether a proof is valid.

SP1 stores multidimensional data in structures called Tensors. A Tensor combines a buffer of stored values with declared dimensions describing its shape, and both must agree for sound verification: the number of stored elements has to equal the product of the declared dimensions.

Each piece of proof data carries a label indicating its size, but the verifier never confirmed that the label matched the actual contents, consulting the label alone. An attacker could therefore submit data carrying a falsified label. Different parts of the check would then read different portions of the same buffer, which meant a fabricated proof could pass.

Version 6.8.1 introduces a length check during deserialization. Any tensor whose number of stored elements does not equal the product of its declared dimensions is rejected.

Who needs to upgrade

Users who request proofs from the mainnet Prover Network do not need to change anything on their end. Operators who run their own native Rust verifier and accept proofs from provers they do not trust must upgrade to 6.8.1. Because Succinct's advisory could only account for the deployments it knew about, self-hosted operators are the ones positioned to check whether their own setups fall inside the affected range, with the advisory's list of impacted releases as the reference.

Disclosure and related incidents

Vitalis Salis discovered the flaw and reported it through Immunefi's bug bounty program, according to the advisory.

The disclosure adds to a series of proof-system soundness issues reported this year. Cryptopolitan previously covered a soundness bug in Zcash's Orchard shielded pool and an exploit at Foom.Cash in which an attacker forged zkSNARK proofs because of a verifier misconfiguration.