Skip to content

Ordinary peer connections never verify a peer's certificate against its claimed ID #40

Description

@Mearman

Found while working on #38/#39 (the federation certificate-pinning fix) — the same gap exists one level deeper, in the default mesh path every bridge uses, not just the optional federation feature.

grep -rn "getPeerCertificate" src/ returns nothing anywhere in the codebase outside #39's own diff. tls-transport.ts's own doc comment claims otherwise:

Do not reject unauthorized — we do our own fingerprint verification after the TLS handshake completes.

That verification doesn't exist. A peer's peerId is established purely by what it self-reports in the introduce/pong wire messages, over a rejectUnauthorized: false TLS connection with no fingerprint check against the actual presented certificate. Nothing stops a connecting socket from claiming any peerId it likes, unrelated to the certificate it's actually presenting.

Why this is separate from #39

Federation is opt-in and, before #39, unreachable in production at all — a real hole, but a contained one. This affects the primary, always-on mesh path (TcpTransport/TlsTransport's startDataServer/connectToCoordinator/connectToPeer), so a fix here touches connection-handling code every bridge depends on, not an optional feature. That's a meaningfully bigger, riskier change to make alongside a scoped federation fix, so it wasn't folded into #39.

Likely fix shape

Same primitive #39 adds for federation — identity.ts's new fingerprintDer() — applied at the point a peer's pong/introduce message is received: verify the claimed peerId against fingerprintDer(socket.getPeerCertificate().raw) before accepting the connection, rather than trusting the self-reported ID. Given the mesh's local-network, no-CA trust model already assumes physical/network proximity as a soft boundary, this is worth scoping carefully — confirm the actual threat model change before implementing, since "any peer ID over an unauthenticated channel" may have been an accepted tradeoff for the LAN case rather than an oversight.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions