From 89197a05c43b18cc4569fd178d56e7bb8f403865 Mon Sep 17 00:00:00 2001 From: bcaller Date: Wed, 13 May 2020 06:37:32 +0100 Subject: [PATCH 1/4] fix: prevent DoS (OOM) via massive packets (#95) When maxHttpBufferSize is large (1e8 bytes), a payload of length 100MB can be sent like so: 99999991:422222222222222222222222222222222222222222222... This massive packet can cause OOM via building up many many `ConsOneByteString` objects due to concatenation: 99999989 `ConsOneByteString`s and then converting the massive integer to a `Number`. The performance can be improved to avoid this by using `substring` rather than building the string via concatenation. Below I tried one payload of length 7e7 as the 1e8 payload took so long to process that it timed out before running out of memory. ``` ==== JS stack trace ========================================= 0: ExitFrame [pc: 0x13c5b79] Security context: 0x152fe7b808d1 1: decodeString [0x2dd385fb5d1] [/node_modules/socket.io-parser/index.js:~276] [pc=0xf59746881be](this=0x175d34c42b69 ,0x14eccff10fe1 ) 2: add [0x31fc2693da29] [/node_modules/socket.io-parser/index.js:242] [bytecode=0xa7ed6554889 offset=11](this=0x0a2881be5069 ,0x14eccff10fe1 Date: Sat, 9 Jan 2021 14:51:19 +0100 Subject: [PATCH 2/4] chore(release): 3.3.2 Diff: https://github.com/Automattic/socket.io-parser/compare/3.3.1...3.3.2 --- CHANGELOG.md | 8 ++++++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c98072..8b1992a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,2 +1,10 @@ +## [3.3.2](https://github.com/Automattic/socket.io-parser/compare/3.3.1...3.3.2) (2021-01-09) + + +### Bug Fixes + +* prevent DoS (OOM) via massive packets ([#95](https://github.com/Automattic/socket.io-parser/issues/95)) ([89197a0](https://github.com/Automattic/socket.io-parser/commit/89197a05c43b18cc4569fd178d56e7bb8f403865)) + + ## [3.3.1](https://github.com/socketio/socket.io-parser/compare/3.3.0...3.3.1) (2020-09-30) diff --git a/package-lock.json b/package-lock.json index 6718338..e7cdf10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "socket.io-parser", - "version": "3.3.1", + "version": "3.3.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 3b39d68..70857ad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "socket.io-parser", - "version": "3.3.1", + "version": "3.3.2", "description": "socket.io protocol parser", "repository": { "type": "git", From fb21e422fc193b34347395a33e0f625bebc09983 Mon Sep 17 00:00:00 2001 From: Damien Arrachequesne Date: Wed, 9 Nov 2022 11:21:11 +0100 Subject: [PATCH 3/4] fix: check the format of the index of each attachment A specially crafted packet could be incorrectly decoded. Example: ```js const decoder = new Decoder(); decoder.on("decoded", (packet) => { console.log(packet.data); // prints [ 'hello', [Function: splice] ] }) decoder.add('51-["hello",{"_placeholder":true,"num":"splice"}]'); decoder.add(Buffer.from("world")); ``` As usual, please remember not to trust user input. Backported from https://github.com/socketio/socket.io-parser/commit/b5d0cb7dc56a0601a09b056beaeeb0e43b160050 --- binary.js | 12 ++++++++++-- index.js | 3 +++ test/buffer.js | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/binary.js b/binary.js index 3e2347d..95a1450 100644 --- a/binary.js +++ b/binary.js @@ -70,8 +70,16 @@ exports.reconstructPacket = function(packet, buffers) { function _reconstructPacket(data, buffers) { if (!data) return data; - if (data && data._placeholder) { - return buffers[data.num]; // appropriate buffer (should be natural order anyway) + if (data && data._placeholder === true) { + var isIndexValid = + typeof data.num === "number" && + data.num >= 0 && + data.num < buffers.length; + if (isIndexValid) { + return buffers[data.num]; // appropriate buffer (should be natural order anyway) + } else { + throw new Error("illegal attachments"); + } } else if (isArray(data)) { for (var i = 0; i < data.length; i++) { data[i] = _reconstructPacket(data[i], buffers); diff --git a/index.js b/index.js index ff613cc..245a800 100644 --- a/index.js +++ b/index.js @@ -239,6 +239,9 @@ Emitter(Decoder.prototype); Decoder.prototype.add = function(obj) { var packet; if (typeof obj === 'string') { + if (this.reconstructor) { + throw new Error("got plaintext data when reconstructing a packet"); + } packet = decodeString(obj); if (exports.BINARY_EVENT === packet.type || exports.BINARY_ACK === packet.type) { // binary packet's json this.reconstructor = new BinaryReconstructor(packet); diff --git a/test/buffer.js b/test/buffer.js index 3aba898..f18e68a 100644 --- a/test/buffer.js +++ b/test/buffer.js @@ -1,8 +1,7 @@ var parser = require('../index.js'); var expect = require('expect.js'); var helpers = require('./helpers.js'); -var encode = parser.encode; -var decode = parser.decode; +var Decoder = parser.Decoder; describe('parser', function() { it('encodes a Buffer', function() { @@ -14,6 +13,15 @@ describe('parser', function() { }); }); + it("encodes a nested Buffer", function() { + helpers.test_bin({ + type: parser.BINARY_EVENT, + data: ["a", { b: ["c", Buffer.from("abc", "utf8")] }], + id: 23, + nsp: "/cool", + }); + }); + it('encodes a binary ack with Buffer', function() { helpers.test_bin({ type: parser.BINARY_ACK, @@ -22,4 +30,39 @@ describe('parser', function() { nsp: '/back' }) }); + + it("throws an error when adding an attachment with an invalid 'num' attribute (string)", function() { + var decoder = new Decoder(); + + expect(function() { + decoder.add('51-["hello",{"_placeholder":true,"num":"splice"}]'); + decoder.add(Buffer.from("world")); + }).to.throwException(/^illegal attachments$/); + }); + + it("throws an error when adding an attachment with an invalid 'num' attribute (out-of-bound)", function() { + var decoder = new Decoder(); + + expect(function() { + decoder.add('51-["hello",{"_placeholder":true,"num":1}]'); + decoder.add(Buffer.from("world")); + }).to.throwException(/^illegal attachments$/); + }); + + it("throws an error when adding an attachment without header", function() { + var decoder = new Decoder(); + + expect(function() { + decoder.add(Buffer.from("world")); + }).to.throwException(/^got binary data when not reconstructing a packet$/); + }); + + it("throws an error when decoding a binary event without attachments", function() { + var decoder = new Decoder(); + + expect(function() { + decoder.add('51-["hello",{"_placeholder":true,"num":0}]'); + decoder.add('2["hello"]'); + }).to.throwException(/^got plaintext data when reconstructing a packet$/); + }); }); From cd11e38e1a3e2146617bc586f86512605607b212 Mon Sep 17 00:00:00 2001 From: Damien Arrachequesne Date: Wed, 9 Nov 2022 11:22:22 +0100 Subject: [PATCH 4/4] chore(release): 3.3.3 Diff: https://github.com/Automattic/socket.io-parser/compare/3.3.2...3.3.3 --- CHANGELOG.md | 9 +++++++++ package.json | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b1992a..a2edc51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [3.3.3](https://github.com/Automattic/socket.io-parser/compare/3.3.2...3.3.3) (2022-11-09) + + +### Bug Fixes + +* check the format of the index of each attachment ([fb21e42](https://github.com/Automattic/socket.io-parser/commit/fb21e422fc193b34347395a33e0f625bebc09983)) + + + ## [3.3.2](https://github.com/Automattic/socket.io-parser/compare/3.3.1...3.3.2) (2021-01-09) diff --git a/package.json b/package.json index 70857ad..9414417 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "socket.io-parser", - "version": "3.3.2", + "version": "3.3.3", "description": "socket.io protocol parser", "repository": { "type": "git", pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy