mirror of
https://github.com/block/buzz.git
synced 2026-10-27 12:40:30 +00:00
fix(channels): restrict private-channel invitations (#4612)
This change requires an active owner or administrator for third-party additions to private channels. The relay validator and transactional database authority enforce the same rule, including removed-member reactivation and role-change paths. Idempotent self-target behavior remains available, while ordinary members can no longer extend private-channel access to another identity. ## Testing - `git diff --check origin/main...codex/security-private-channel-invite-authority` - Rebased onto `origin/main` at `5c98932` - Full CI pending Originating Buzz thread: `buzz://message?channel=3928fe05-df61-4b5d-b9c7-d623b9b10ea1&id=3c6c02312f763fbe0d2bfc33a6c1a362f91d0354f3d18b039cf7a0558c1439d1` --------- Signed-off-by: Jordan Mecom <jm@squareup.com> Signed-off-by: Eli Foster <efoster@squareup.com> Co-authored-by: Eli Foster <efoster@squareup.com>
This commit is contained in:
@@ -371,7 +371,9 @@ async fn acquire_channel_membership_lock(
|
||||
/// Role enforcement:
|
||||
/// - Open channels: `invited_by` is optional; role is forced to `Member` regardless of
|
||||
/// what the caller passes — callers cannot self-assign elevated roles.
|
||||
/// - Private channels: requires an `invited_by` who is an active owner/admin.
|
||||
/// - Private channels: requires an `invited_by` who is an active owner/admin, the channel
|
||||
/// creator bootstrapping their own first membership, or the target adding themselves
|
||||
/// (idempotent re-add — an active member's *role* still cannot change this way).
|
||||
/// - Elevated roles (`Owner`, `Admin`) may only be granted by an existing owner/admin,
|
||||
/// even on open channels.
|
||||
///
|
||||
@@ -419,10 +421,14 @@ pub async fn add_member(
|
||||
DbError::InvalidData(format!("invalid role in database: {inviter_role_str}"))
|
||||
})?;
|
||||
|
||||
// Any member can invite others, but only owners/admins may grant elevated roles.
|
||||
if role.is_elevated() && !inviter_role.is_elevated() {
|
||||
// Only owners/admins may extend private-channel access to another
|
||||
// identity. `inviter == pubkey` keeps a member's own idempotent
|
||||
// re-add working; it is not a role-escalation hole, because the
|
||||
// active-role-change guard below still rejects a self-targeted
|
||||
// promotion from any non-elevated caller.
|
||||
if !inviter_role.is_elevated() && inviter != pubkey {
|
||||
return Err(DbError::AccessDenied(
|
||||
"only owners/admins may grant elevated roles".to_string(),
|
||||
"only owners/admins may add private-channel members".to_string(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user