Skip to content

[Security][tentative] Medium (attackable): SSZ State Root Omits Pending Checkpoint #258

@evonide

Description

@evonide

Context

Summit's finalizer prepares checkpoint data around epoch boundaries. At the penultimate block it stores a pending_checkpoint, and the last block carries the checkpoint hash that commits the boundary artifact into the finalized chain.

The intended invariant is that the advertised SSZ state root for checkpoint or proof consumers authenticates the consensus-state fields needed to verify the next boundary transition. pending_checkpoint is one of those fields because it determines the checkpoint digest that the boundary header is expected to carry.

Claim

pending_checkpoint is serialized state used to derive the next boundary checkpoint_hash, but it is omitted from the SSZ state root used for parent_beacon_block_root.

A malicious checkpoint producer or state artifact supplier can persist or serve consensus state with a serialized pending_checkpoint that differs from the value expected by a consumer while advertising the same SSZ state root, because pending_checkpoint is omitted from the root tree and the root alone cannot bind the next boundary checkpoint digest.

Flow

Reachable for SSZ roots and proofs captured after the finalizer sets pending_checkpoint at the penultimate block, because set_pending_checkpoint does not update the tree and the full rebuild omits the field. The validated start condition is a state/proof artifact whose serialized pending_checkpoint differs from the value a consumer expects; live boundary block verification still checks the header checkpoint_hash separately.

Impact

The finalized/proved state root can omit the checkpoint artifact the chain is about to finalize. Restarted, checkpoint-derived, or proof-consuming nodes can accept a state root that does not commit to the pending checkpoint digest used at the epoch boundary, weakening the root-binds-state invariant.

Root Cause

pending_checkpoint is part of serialized consensus state but is excluded from the SSZ state tree leaves and is not reflected by set_pending_checkpoint.

Code

Related Issues/PRs

Related issues cover adjacent pending-checkpoint validation and SSZ root omissions across dynamic epoch, pending execution, and proof response state.

Fix

  • Add pending_checkpoint to the SSZ state tree or remove it from consensus state and derive it deterministically from committed fields.
  • Ensure state-root tests change when only pending_checkpoint changes.
  • Version roots/checkpoints if the committed state layout changes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions