From 5e993e50a2e393a6724e8f80e9f94c80922e320d Mon Sep 17 00:00:00 2001 From: heapwolf Date: Thu, 21 Dec 2023 10:23:14 +0100 Subject: [PATCH] harden protocol decode --- api/stream-relay/cache.js | 2 +- api/stream-relay/packets.js | 40 +++++++++++++++++++++---------------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/api/stream-relay/cache.js b/api/stream-relay/cache.js index bfed6f8ed..1893b72a9 100644 --- a/api/stream-relay/cache.js +++ b/api/stream-relay/cache.js @@ -196,7 +196,7 @@ export class Cache { // follow the chain to get the buffers in order const bufs = [...source.values()] - .filter(p => p.previousId.toString('hex') === previous.packetId.toString('hex')) + .filter(p => Buffer.from(p.previousId).toString('hex') === Buffer.from(previous.packetId).toString('hex')) .sort((a, b) => a.index - b.index) if (!indexes || bufs.length < indexes) return null diff --git a/api/stream-relay/packets.js b/api/stream-relay/packets.js index 8478c1710..c107333be 100644 --- a/api/stream-relay/packets.js +++ b/api/stream-relay/packets.js @@ -200,27 +200,33 @@ export const decode = buf => { for (const [k, spec] of Object.entries(PACKET_SPEC)) { o[k] = spec.default - if (spec.encoding === 'number') { - const method = getMethod('read', spec.bytes, spec.signed) - o[k] = buf[method](offset) - offset += spec.bytes - continue - } + try { + if (spec.encoding === 'number') { + const method = getMethod('read', spec.bytes, spec.signed) + o[k] = buf[method](offset) + offset += spec.bytes + continue + } - const size = buf.readUInt16BE(offset) - offset += SIZE - let value = buf.slice(offset, offset + size) - offset += size + const size = buf.readUInt16BE(offset) + offset += SIZE + let value = buf.slice(offset, offset + size) + offset += size - if (spec.encoding === 'hex') value = Buffer.from(value, 'hex') - if (spec.encoding === 'base64') value = Buffer.from(value, 'base64') - if (spec.encoding === 'utf8') value = value.toString() + if (spec.bytes && size > spec.bytes) return null - if (k === 'message' && isEncodedAsJSON(o)) { - try { value = JSON.parse(value.toString()) } catch {} - } + if (spec.encoding === 'hex') value = Buffer.from(value, 'hex') + if (spec.encoding === 'base64') value = Buffer.from(value, 'base64') + if (spec.encoding === 'utf8') value = value.toString() + + if (k === 'message' && isEncodedAsJSON(o)) { + try { value = JSON.parse(value.toString()) } catch {} + } - o[k] = value + o[k] = value + } catch (err) { + return null // completely bail + } } return o