diff options
Diffstat (limited to 'packages/meshbay-hub/src')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/transport.js | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/transport.js b/packages/meshbay-hub/src/meshbay_hub/static/transport.js index 0bffeae..624c3c3 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/transport.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/transport.js @@ -248,6 +248,10 @@ class MeshBayTransport { // Kept for the life of the connection: a join_request is signed over it, // which is what stops one being lifted onto another connection. this._nonceNode = nonceNode; + // Announced in the challenge because joining needs it before the ack: a + // first-time member has no GEK, so they cannot complete the handshake that + // would prove this key. Unverified here; checked against the ack below. + this.nodePk = reply.node_pk || null; const gid = groupId || ''; const proof = await C.handshakeProof( @@ -281,6 +285,12 @@ class MeshBayTransport { // fails the GEK proof — this covers the case where an attacker HAS the GEK // (an ex-member, or a leaked key) and swaps the node underneath. // Strict refusal: a warning users can click through is decorative. + // The key announced in the challenge must be the one that just proved + // itself. A peer that changed identity mid-handshake is not one to trust + // with anything, including a join we may already have signed for it. + if (this.nodePk && this.nodePk !== ack.node_pk) { + throw new Error('Node identity changed during the handshake — refusing'); + } _checkNodePin(nodeId, ack.node_pk); this.nodePk = ack.node_pk; |