Commit: 2f26d91 · Finding: SEC-V-06
Problem
The relay's topic subscription listener at crates/relay/src/lib.rs:371-423 caps the total subscribed-topic set at MAX_TOPICS = 10_000 but iterates topics per-message unbounded. topics: Vec<String> is declared at crates/common/src/wire.rs:76 with no per-message cap.
256 KB of 2-byte topic strings ≈ 128,000 topic entries to process in one message — each calls topic_str_is_valid (O(n) on length) and willow_network::topic_id (a blake3 hash).
Additionally, topics are never removed once added, so a peer can pump up to 10,000 attacker-controlled topics into the slot table and deny legitimate clients' announces thereafter.
Fix
- Cap
topics.len() per announce (e.g. 64) before iterating; reject messages exceeding the cap.
- Enforce a per-signer subscription cap (e.g. 100 topics per announcing peer) with LRU eviction so one peer cannot monopolise all 10,000 slots.
- Upgrade the existing
warned_full log from once-per-session to rate-limited (1 per minute), so operators see the wall.
Commit:
2f26d91· Finding:SEC-V-06Problem
The relay's topic subscription listener at
crates/relay/src/lib.rs:371-423caps the total subscribed-topic set atMAX_TOPICS = 10_000but iteratestopicsper-message unbounded.topics: Vec<String>is declared atcrates/common/src/wire.rs:76with no per-message cap.256 KB of 2-byte topic strings ≈ 128,000 topic entries to process in one message — each calls
topic_str_is_valid(O(n) on length) andwillow_network::topic_id(a blake3 hash).Additionally, topics are never removed once added, so a peer can pump up to 10,000 attacker-controlled topics into the slot table and deny legitimate clients' announces thereafter.
Fix
topics.len()per announce (e.g. 64) before iterating; reject messages exceeding the cap.warned_fulllog from once-per-session to rate-limited (1 per minute), so operators see the wall.