mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-08-08 06:56:10 +00:00
cover group removal path
This commit is contained in:
parent
c836b10d68
commit
cf2a1e77ec
@ -77,14 +77,17 @@ final class GroupStore: ObservableObject {
|
||||
!group.members.isEmpty,
|
||||
group.members.count <= BitchatGroup.maxMembers,
|
||||
group.creator != nil else { return false }
|
||||
// A group keeps the creator it was created with. `applyGroupState`
|
||||
// checks the sender is the creator the state NAMES, but never against
|
||||
// the creator already stored, so a peer naming themselves creator of a
|
||||
// known groupID at a higher epoch replaces the roster and key wholesale.
|
||||
// Pinned here, the one point every write goes through.
|
||||
// A group keeps the creator it was created with. A peer naming
|
||||
// themselves creator of a known groupID at a higher epoch would
|
||||
// otherwise replace the roster and key wholesale. `applyGroupState`
|
||||
// pins this before its removal branch; here is the one point every
|
||||
// write goes through.
|
||||
if let existing = groups.first(where: { $0.groupID == group.groupID }),
|
||||
existing.creatorFingerprint != group.creatorFingerprint {
|
||||
SecureLogger.warning("Refusing group state that changes the creator of an existing group", category: .security)
|
||||
SecureLogger.warning(
|
||||
"Refusing group state: creator \(group.creatorFingerprint.prefix(8))… does not match stored creator \(existing.creatorFingerprint.prefix(8))…",
|
||||
category: .security
|
||||
)
|
||||
return false
|
||||
}
|
||||
guard keychain.saveIdentityKey(key, forKey: Self.keychainKey(for: group.groupID)) else {
|
||||
|
||||
@ -558,6 +558,18 @@ private extension ChatGroupCoordinator {
|
||||
let myFingerprint = context.myNoiseFingerprint()
|
||||
let existing = context.groupStore.group(withID: state.groupID)
|
||||
|
||||
// A group keeps the creator it was created with. The checks above only
|
||||
// prove the sender is the creator the state names, which an attacker
|
||||
// satisfies by naming themselves. Checked before the removal branch,
|
||||
// which drops the group without ever reaching `upsert`.
|
||||
if let existing, existing.creatorFingerprint != state.creatorFingerprint {
|
||||
SecureLogger.warning(
|
||||
"Dropping group state claiming creator \(state.creatorFingerprint.prefix(8))… for a group created by \(existing.creatorFingerprint.prefix(8))…",
|
||||
category: .security
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// A creator-signed roster that no longer includes us is a removal.
|
||||
guard state.members.contains(where: { $0.fingerprint == myFingerprint }) else {
|
||||
if let existing {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user