-
Notifications
You must be signed in to change notification settings - Fork 31
Description
- Context:
provekit/verifier/src/lib.rs
Description
The Verifier::verify uses self.whir_for_witness.take().unwrap(), which
(1) will panic if whir_for_witness is None (e.g., a Verifier deserialized from untrusted input with the field omitted/null), and
(2) permanently consumes the whir_for_witness state even on verification failure, making subsequent verify calls on the same Verifier panic.
In a long-running process that reuses a single Verifier across requests, an attacker can trigger a denial-of-service by causing a first verification attempt (valid or invalid) that drains whir_for_witness, then any later verification call crashes the process/thread via the unwrap() panic.
- Impacted code
impl Verify for Verifier {
#[instrument(skip_all)]
fn verify(&mut self, proof: &NoirProof) -> Result<()> {
self.whir_for_witness.take().unwrap().verify(
&proof.whir_r1cs_proof,
&proof.public_inputs,
&self.r1cs,
)?;
Ok(())
}
}Recommendation
Avoid panics and avoid consuming verifier state on verification. Prefer let whir = self.whir_for_witness.as_ref().ok_or_else(|| anyhow!(...))?; whir.verify(...) or, if the intent is to consume, change the API to take self by value (one-shot verifier) or restore the value after the call. Replace unwrap() with error propagation.