File: crates/state/src/materialize.rs:456-470
Severity: security
Obvious? no
EventKind::GrantPermission calls state.members.entry(*peer_id).or_insert_with(|| Member { ... }). An admin can therefore unilaterally add an arbitrary peer_id to membership simply by granting any permission to it, with no requirement that the peer ever signed a join event. Combined with MuteChannel/MuteGrove not requiring permission, this lets an admin silently materialize "ghost members" in state.members. The GrantAdmin path (line 216) does the same but is at least gated by ProposedAction + vote. See sibling issue F9 (AssignRole compounding).
Fix: require the target be already in members (i.e. has self-published SetProfile / has joined), or split member-creation from permission-granting.
Filed by /general-audit @ 6404719 (2026-05-03). master: #567.
File:
crates/state/src/materialize.rs:456-470Severity: security
Obvious? no
EventKind::GrantPermissioncallsstate.members.entry(*peer_id).or_insert_with(|| Member { ... }). An admin can therefore unilaterally add an arbitrarypeer_idto membership simply by granting any permission to it, with no requirement that the peer ever signed a join event. Combined withMuteChannel/MuteGrovenot requiring permission, this lets an admin silently materialize "ghost members" instate.members. TheGrantAdminpath (line 216) does the same but is at least gated by ProposedAction + vote. See sibling issue F9 (AssignRole compounding).Fix: require the target be already in
members(i.e. has self-publishedSetProfile/ has joined), or split member-creation from permission-granting.Filed by
/general-audit@6404719(2026-05-03). master: #567.