Skip to content

[vuln] Fix announce trust anchoring#1094

Draft
jmecom wants to merge 5 commits intopermissionlesstech:mainfrom
jmecom:jm/fix-spoofing
Draft

[vuln] Fix announce trust anchoring#1094
jmecom wants to merge 5 commits intopermissionlesstech:mainfrom
jmecom:jm/fix-spoofing

Conversation

@jmecom
Copy link
Copy Markdown
Contributor

@jmecom jmecom commented Apr 7, 2026

Summary

This PR fixes the BLE identity-spoofing path by removing unauthenticated signing-key trust, requiring a trusted signing key for public content, revoking that trust immediately when a user removes verification, clearing stale stored signing keys during manual fingerprint verification, clearing the active session's in-memory public signing-key trust during manual verification, and persisting cryptographic identities so returning peers can be authenticated consistently across app restarts.

Why this was a security problem

The original flow had several related trust failures:

  • announce packets could introduce an attacker-controlled signing key before any trusted binding existed
  • manual fingerprint verification could persist or preserve a signing key even though the user had only verified the Noise fingerprint, not the public-message signing key
  • once a peer was treated as trusted in memory, public messages and file transfers were accepted without enforcing a valid packet signature, and that in-memory trust could outlive later verification removal or manual re-verification
  • the code also treated cryptographic identities as if they were durable trusted state even though they were not actually persisted, which made the returning-peer trust path inconsistent

That meant a nearby attacker could poison the public-identity trust anchor ahead of verification, inject unsigned public content under a trusted peer identity, survive manual re-verification inside the same live session, or rely on mismatched runtime-vs-persisted trust behavior after restart.

Fix

  • keep first-contact announces discoverable, but do not retain or trust the advertised signing key unless the announce authenticates against an already trusted signing key
  • make manual Mark Verified persist only the verified Noise identity; it no longer anchors a public-message signing key
  • explicitly clear any previously stored signing key when the user manually verifies a fingerprint, so older poisoned state does not survive re-verification
  • explicitly clear the active session's in-memory trusted signing key when a user manually verifies or removes verification, so public identity trust is not silently retained across trust-state changes
  • keep QR verification as the OOB path that can safely persist the signing key, since the QR payload carries that key through the verified challenge/response flow
  • require a valid packet signature from a trusted signing key for public messages and file transfers, including already-known in-memory peers
  • persist cryptographic identities in the encrypted identity cache so the returning-peer authentication path is actually durable and consistent with the runtime trust model
  • re-check persisted verification state before trusting active-session signing keys, so removing verification revokes public trust immediately without requiring reconnect or restart
  • clarify the fingerprint screen so it distinguishes fingerprint verification from trusted public signing-key verification

User impact

  • spoofed first-contact announces no longer seed a trusted signing key
  • unsigned public messages and file transfers from trusted-looking peers are rejected
  • removing verification now revokes public signed-content trust immediately for the active session
  • manual fingerprint verification no longer preserves either stored or in-memory public signing-key trust
  • returning peers can still be authenticated after restart because the trusted cryptographic identity is now actually persisted
  • manual fingerprint verification still marks the Noise identity verified, but public-message authentication now depends on a signing key that was actually verified out of band
  • QR-verified peers continue to work for authenticated public identity and content

Validation

  • swift test --filter BLEServiceCoreTests
  • swift test --filter ChatViewModelVerificationTests
  • swift test --filter SecureIdentityStateManagerTests
  • swift test --filter ProtocolContractTests
  • swift test --filter VerificationServiceTests

@jmecom jmecom changed the title [codex] fix announce trust anchoring [vuln] Fix announce trust anchoring Apr 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant