From 241ce2d52c3ddff77bc08f992d5ff85ec27ff796 Mon Sep 17 00:00:00 2001 From: jack Date: Mon, 12 Jan 2026 18:34:59 -1000 Subject: [PATCH] Fix topology update running before announce verification Move updateNeighbors call to after signature verification passes, preventing spoofed or stale announces from injecting bad routing data. Also reset isNewPeer/isReconnectedPeer flags on verification failure to prevent spurious peer connection notifications. Addresses review feedback from PR #938. Co-Authored-By: Claude Opus 4.5 --- bitchat/Services/BLE/BLEService.swift | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/bitchat/Services/BLE/BLEService.swift b/bitchat/Services/BLE/BLEService.swift index 83597cd9..3bb1abf5 100644 --- a/bitchat/Services/BLE/BLEService.swift +++ b/bitchat/Services/BLE/BLEService.swift @@ -3580,11 +3580,6 @@ extension BLEService { return } - // Update topology with their claimed neighbors - if let neighbors = announcement.directNeighbors { - meshTopology.updateNeighbors(for: peerID.routingData, neighbors: neighbors) - } - // Verify that the sender's derived ID from the announced noise public key matches the packet senderID // This helps detect relayed or spoofed announces. Only warn in release; assert in debug. let derivedFromKey = PeerID(publicKey: announcement.noisePublicKey) @@ -3657,6 +3652,9 @@ extension BLEService { // Require verified announce; ignore otherwise (no backward compatibility) if !verified { SecureLogger.warning("❌ Ignoring unverified announce from \(peerID.id.prefix(8))…", category: .security) + // Reset flags to prevent post-barrier code from acting on unverified announces + isNewPeer = false + isReconnectedPeer = false return } @@ -3704,6 +3702,11 @@ extension BLEService { } } + // Update topology with verified neighbor claims (only for authenticated announces) + if verifiedAnnounce, let neighbors = announcement.directNeighbors { + meshTopology.updateNeighbors(for: peerID.routingData, neighbors: neighbors) + } + // Persist cryptographic identity and signing key for robust offline verification identityManager.upsertCryptographicIdentity( fingerprint: announcement.noisePublicKey.sha256Fingerprint(),