java-topology/defects/substrate/substrate-0002-aura-babe-beefy-is-member-linear.md

1.5 KiB
Raw Blame History

substrate-0002: CWE-407 — Aura/BABE/BEEFY is_member() linear authority scan

Severity: MEDIUM Files:

  • substrate/frame/aura/src/lib.rs:443
  • substrate/frame/babe/src/lib.rs:508
  • substrate/frame/beefy/src/lib.rs:738 Function: IsMember::is_member

Description

All three consensus pallets implement IsMember::is_member using .iter().any(|id| id == authority_id) — an O(A) linear scan over the authority list. The authority list can grow to the configured validator set size (typical: 1001000 validators).

is_member is part of the IsMember trait used by other pallets to gate authority-only calls, including session management and equivocation reports. While not called on every block unconditionally, any extrinsic validation path that calls is_member pays O(A) per call.

Root Cause

// aura/src/lib.rs:443
Authorities::<T>::get().iter().any(|id| id == authority_id)

The authority list is stored as a BoundedVec. The fix is to either:

  1. Use a BTreeSet / StorageMap keyed by authority ID for O(log A) lookup, or
  2. Sort the BoundedVec and use binary search for O(log A).

Fix

Replace linear .iter().any() with a sorted binary search or an auxiliary AuthoritiesSet storage map for O(1) membership checks.

Speedup

At A=1000 authorities: ~500× fewer comparisons on average (binary search: ~10). Practical speedup bounded by authority set size; at Polkadot scale (~300): ~150×.

Status

PATCHED (see patch/substrate-0002-is-member-binarysearch.patch)