Skip to content

Commit ff6590d

Browse files
committed
fix: add bounds checks for proof node size and count in verify_proof
Enforce MAX_PROOF_NODE_SIZE (1024 bytes) and MAX_PROOF_NODES (65) limits in verify_proof to prevent memory/CPU exhaustion from malicious proofs with oversized RLP payloads or excessive node counts. The node count is validated upfront before any decoding, and individual node sizes are checked before RLP decoding in each iteration.
1 parent 24e6b13 commit ff6590d

1 file changed

Lines changed: 17 additions & 0 deletions

File tree

src/proof/verify.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@ pub fn verify_proof<'a, I>(
3737
where
3838
I: IntoIterator<Item = &'a Bytes>,
3939
{
40+
let proof: Vec<&'a Bytes> = proof.into_iter().collect();
41+
42+
// Enforce maximum proof node count.
43+
if proof.len() > MAX_PROOF_NODES {
44+
return Err(ProofVerificationError::TooManyProofNodes {
45+
got: proof.len(),
46+
max: MAX_PROOF_NODES,
47+
});
48+
}
49+
4050
let mut proof = proof.into_iter().peekable();
4151

4252
// If the proof is empty or contains only an empty node, the expected value must be None.
@@ -62,6 +72,13 @@ where
6272
let mut last_decoded_node = Some(NodeDecodingResult::Node(RlpNode::word_rlp(&root)));
6373
let mut last_decoded_node_is_private = false;
6474
for node in proof {
75+
// Enforce maximum proof node size.
76+
if node.len() > MAX_PROOF_NODE_SIZE {
77+
return Err(ProofVerificationError::ProofNodeTooLarge {
78+
got: node.len(),
79+
max: MAX_PROOF_NODE_SIZE,
80+
});
81+
}
6582
// Check if the node that we just decoded (or root node, if we just started) matches
6683
// the expected node from the proof.
6784
if Some(RlpNode::from_rlp(node).as_slice()) != last_decoded_node.as_deref() {

0 commit comments

Comments
 (0)