Context
Summit's state-proof RPC lets external consumers request Merkle proofs for consensus-state fields and verify those proofs against a returned state root. Batched requests are intended to preserve the caller's association between each requested key and each returned proof.
This finding concerns the batch response shape when some requested keys cannot be proven. The normal flow is that every requested key should either produce a proof or an explicit per-key failure so consumers do not have to infer which proof corresponds to which request.
Claim
getStateProof accepts batched key requests, but proof generation uses filter_map, so any key whose proof returns None is silently omitted. The response then contains a shorter proof list with no echoed key or per-key status, allowing positional consumers to associate later proofs with the wrong requested fields.
A batched getStateProof request mixes valid keys with absent or out-of-range keys. Summit silently drops the missing entries instead of preserving one result per request, so a downstream consumer that relies on positional association can map returned proofs to the wrong requested fields.
Flow
The path is reachable through the RPC state-proof endpoint whenever a batch mixes provable keys with keys whose proof generator returns None. The start condition is ambiguous client/API semantics, not an RPC caller directly gaining authority by attacking its own request; impact requires a positional downstream consumer because the response does not echo request keys or statuses.
Impact
A consumer that maps returned proofs to requested keys by position can be shifted by an attacker-controlled missing key. Each Merkle proof may verify against the returned root while being interpreted as proof for a different requested field, misleading external proof consumers, accounting systems, or contracts that rely on batched responses.
Root Cause
Batch proof generation uses filter_map, which removes failed proof requests instead of preserving request cardinality with an explicit missing result or error.
Code
Related Issues/PRs
Related issues cover adjacent state-proof, SSZ root, keyed collection, and response-shape issues that can make proof consumers accept incomplete data.
Fix
- Return one result per requested key, preserving cardinality.
- Include explicit missing/error status for unprovable keys.
- Echo the canonical key descriptor with every returned proof.
- Update docs and tests to define batch semantics precisely.
Context
Summit's state-proof RPC lets external consumers request Merkle proofs for consensus-state fields and verify those proofs against a returned state root. Batched requests are intended to preserve the caller's association between each requested key and each returned proof.
This finding concerns the batch response shape when some requested keys cannot be proven. The normal flow is that every requested key should either produce a proof or an explicit per-key failure so consumers do not have to infer which proof corresponds to which request.
Claim
getStateProofaccepts batched key requests, but proof generation usesfilter_map, so any key whose proof returnsNoneis silently omitted. The response then contains a shorter proof list with no echoed key or per-key status, allowing positional consumers to associate later proofs with the wrong requested fields.A batched
getStateProofrequest mixes valid keys with absent or out-of-range keys. Summit silently drops the missing entries instead of preserving one result per request, so a downstream consumer that relies on positional association can map returned proofs to the wrong requested fields.Flow
The path is reachable through the RPC state-proof endpoint whenever a batch mixes provable keys with keys whose proof generator returns
None. The start condition is ambiguous client/API semantics, not an RPC caller directly gaining authority by attacking its own request; impact requires a positional downstream consumer because the response does not echo request keys or statuses.Impact
A consumer that maps returned proofs to requested keys by position can be shifted by an attacker-controlled missing key. Each Merkle proof may verify against the returned root while being interpreted as proof for a different requested field, misleading external proof consumers, accounting systems, or contracts that rely on batched responses.
Root Cause
Batch proof generation uses
filter_map, which removes failed proof requests instead of preserving request cardinality with an explicit missing result or error.Code
getStateProofas returning anSszProoffor each key: https://github.com/SeismicSystems/summit/blob/ed2c5c8/docs/ssz-merklization.md#L372.filter_map, dropping keys whose proof function returnsNone: https://github.com/SeismicSystems/summit/blob/ed2c5c8/finalizer/src/actor.rs#L1107.Nonefor absent or out-of-range items: https://github.com/SeismicSystems/summit/blob/ed2c5c8/types/src/ssz_state_tree.rs#L987, https://github.com/SeismicSystems/summit/blob/ed2c5c8/types/src/ssz_state_tree.rs#L1085, https://github.com/SeismicSystems/summit/blob/ed2c5c8/types/src/ssz_state_tree.rs#L1330, https://github.com/SeismicSystems/summit/blob/ed2c5c8/types/src/ssz_state_tree.rs#L1425, https://github.com/SeismicSystems/summit/blob/ed2c5c8/types/src/ssz_state_tree.rs#L1500.StateProofResponseincludesroot,el_block_number, andproofs, but no request key echo or per-key status: https://github.com/SeismicSystems/summit/blob/ed2c5c8/types/src/rpc.rs#L66.Related Issues/PRs
Related issues cover adjacent state-proof, SSZ root, keyed collection, and response-shape issues that can make proof consumers accept incomplete data.
Fix