Skip to content

audit F1 [robustness]: replay/role.rs missing storage's heads-cap rejection #514

@intendednull

Description

@intendednull

File: crates/replay/src/role.rs:275
Severity: robustness — availability
Obvious? yes — sibling-of-closed (#507 b075140)

PR #507 / b075140 capped peer-supplied HeadsSummary at MAX_AUTHORS_PER_SYNC = 256 in crates/storage/src/store.rs (sync_since + history) to defeat oversized cursors that would blow SQLite bind-parameter / expression-tree limits or just waste CPU compiling huge SQL.

Replay's handle_request(WorkerRequest::Sync { server_id, heads }) does the same per-author iteration on a peer-supplied HeadsSummary (heads.heads.iter().map(...).collect() then events_since) with no cap — malicious peer sends a multi-thousand-entry summary, forces O(N) BTreeMap inserts + walk through in-memory DAG. Identical DoS shape, trivially fixed by gating with the same constant.


Filed by /general-audit @ b901575 (2026-05-02). master: #513.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions