From b914127f3058e54503319a31c25878a3d6e2cda5 Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Sat, 9 Sep 2023 09:36:47 +0200 Subject: [PATCH 1/4] add replay protection to core encode/decode --- packages/core/src/controllers/crypto.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/core/src/controllers/crypto.ts b/packages/core/src/controllers/crypto.ts index fa649c3c4..511469983 100644 --- a/packages/core/src/controllers/crypto.ts +++ b/packages/core/src/controllers/crypto.ts @@ -106,7 +106,8 @@ export class Crypto implements ICrypto { public encode: ICrypto["encode"] = async (topic, payload, opts) => { this.isInitialized(); const params = validateEncoding(opts); - const message = safeJsonStringify(payload); + const protectedPayload = { topic, ...payload }; + const message = safeJsonStringify(protectedPayload); if (isTypeOneEnvelope(params)) { const selfPublicKey = params.senderPublicKey; const peerPublicKey = params.receiverPublicKey; @@ -130,6 +131,9 @@ export class Crypto implements ICrypto { const symKey = this.getSymKey(topic); const message = decrypt({ symKey, encoded }); const payload = safeJsonParse(message); + if (typeof payload.topic !== "undefined" && payload.topic !== topic) { + throw new Error("Mismatched topic decoded from message"); + } return payload; } catch (error) { this.logger.error( From 11900088fc18347a6dfb0f612db0235084d521b6 Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Sat, 9 Sep 2023 10:00:42 +0200 Subject: [PATCH 2/4] delete topic from jsonrpc payload --- packages/core/src/controllers/crypto.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/core/src/controllers/crypto.ts b/packages/core/src/controllers/crypto.ts index 511469983..84e6cba78 100644 --- a/packages/core/src/controllers/crypto.ts +++ b/packages/core/src/controllers/crypto.ts @@ -132,7 +132,10 @@ export class Crypto implements ICrypto { const message = decrypt({ symKey, encoded }); const payload = safeJsonParse(message); if (typeof payload.topic !== "undefined" && payload.topic !== topic) { - throw new Error("Mismatched topic decoded from message"); + if (payload.topic !== topic) { + throw new Error("Mismatched topic decoded from message"); + } + delete payload.topic; } return payload; } catch (error) { From 4ca2e20c1050351c109683ab23add6886f54eefa Mon Sep 17 00:00:00 2001 From: Gancho Radkov Date: Mon, 11 Sep 2023 12:08:34 +0300 Subject: [PATCH 3/4] fix: sets topic after handling for `type-1` payloads is done --- packages/core/src/controllers/crypto.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/src/controllers/crypto.ts b/packages/core/src/controllers/crypto.ts index 84e6cba78..d8baa9594 100644 --- a/packages/core/src/controllers/crypto.ts +++ b/packages/core/src/controllers/crypto.ts @@ -106,13 +106,13 @@ export class Crypto implements ICrypto { public encode: ICrypto["encode"] = async (topic, payload, opts) => { this.isInitialized(); const params = validateEncoding(opts); - const protectedPayload = { topic, ...payload }; - const message = safeJsonStringify(protectedPayload); if (isTypeOneEnvelope(params)) { const selfPublicKey = params.senderPublicKey; const peerPublicKey = params.receiverPublicKey; topic = await this.generateSharedKey(selfPublicKey, peerPublicKey); } + const protectedPayload = { topic, ...payload }; + const message = safeJsonStringify(protectedPayload); const symKey = this.getSymKey(topic); const { type, senderPublicKey } = params; const result = encrypt({ type, symKey, message, senderPublicKey }); From 4d1724fb844c20fa859fc3bbc07d1b2285f73bcb Mon Sep 17 00:00:00 2001 From: Gancho Radkov Date: Mon, 11 Sep 2023 16:49:52 +0300 Subject: [PATCH 4/4] fix: topic comparisons --- packages/core/src/controllers/crypto.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/controllers/crypto.ts b/packages/core/src/controllers/crypto.ts index d8baa9594..9d33b1f88 100644 --- a/packages/core/src/controllers/crypto.ts +++ b/packages/core/src/controllers/crypto.ts @@ -131,7 +131,7 @@ export class Crypto implements ICrypto { const symKey = this.getSymKey(topic); const message = decrypt({ symKey, encoded }); const payload = safeJsonParse(message); - if (typeof payload.topic !== "undefined" && payload.topic !== topic) { + if (typeof payload.topic !== "undefined") { if (payload.topic !== topic) { throw new Error("Mismatched topic decoded from message"); }