Compare commits

..

15 Commits

Author SHA1 Message Date
Damien Arrachequesne
082b68394f chore(release): socket.io-parser@3.4.4 2026-03-17 15:52:17 +01:00
Damien Arrachequesne
3263ce0f13 ci: init publish workflow 2026-03-17 15:44:42 +01:00
Damien Arrachequesne
719f9ebab0 fix(parser): add a limit to the number of binary attachments
Backported from main: b25738c416

When a packet contains binary elements, the built-in parser does not modify them and simply sends them in their own WebSocket frame.

Example: `socket.emit("some event", Buffer.of(1,2,3))`

is encoded and transferred as:

- 1st frame: 51-["some event",{"_placeholder":true,"num":0}]
- 2nd frame: <buffer 01 02 03>

where:

- `5` is the type of the packet (binary message)
- `1` is the number of binary attachments
- `-` is the separator
- `["some event",{"_placeholder":true,"num":0}]` is the payload (including the placeholder)

On the receiving end, the parser reads the number of attachments and buffers them until they are all received.

Before this change, the built-in parser accepted any number of binary attachments, which could be exploited to make the server run out of memory.

The number of attachments is now limited to 10, which should be sufficient for most use cases.

The limit can be increased with a custom `parser`:

```js
import { Encoder, Decoder } from "socket.io-parser";

const io = new Server({
  parser: {
    Encoder,
    Decoder: class extends Decoder {
      constructor() {
        super({
          maxAttachments: 20
        });
      }
    }
  }
});
```
2026-03-17 15:41:29 +01:00
Damien Arrachequesne
d256cf1efc ci: init workflow 2026-03-17 15:28:51 +01:00
Damien Arrachequesne
060339a206 chore(release): 3.4.3
Diff: https://github.com/socketio/socket.io-parser/compare/3.4.2...3.4.3
2023-05-22 10:00:23 +02:00
Damien Arrachequesne
2dc3c92622 fix: check the format of the event name
A packet like '2[{"toString":"foo"}]' was decoded as:

{
  type: EVENT,
  data: [ { "toString": "foo" } ]
}

Which would then throw an error when passed to the EventEmitter class:

> TypeError: Cannot convert object to primitive value
>    at Socket.emit (node:events:507:25)
>    at .../node_modules/socket.io/lib/socket.js:531:14

History of the isPayloadValid() method:

- added in [78f9fc2](78f9fc2) (v4.0.1, socket.io@3.0.0)
- updated in [1c220dd](1c220dd) (v4.0.4, socket.io@3.1.0)

Backported from 3b78117bf6
2023-05-22 09:56:28 +02:00
Damien Arrachequesne
4b3c191bc4 chore(release): 3.4.2
Diff: https://github.com/socketio/socket.io-parser/compare/3.4.1...3.4.2
2022-11-09 11:18:30 +01:00
Damien Arrachequesne
04d23cecaf 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 b5d0cb7dc5
2022-11-09 11:04:00 +01:00
Damien Arrachequesne
6a59237ed0 test: add Node.js 12 and 14 in the build matrix
Node.js 8 is removed, as it is now EOL.

Note: the node_modules folder is cached by default
2020-09-17 15:27:33 +02:00
Damien Arrachequesne
a8130ce3a9 chore: release 3.4.1
Diff: https://github.com/socketio/socket.io-parser/compare/3.4.0...3.4.1
2020-05-13 07:59:21 +02:00
bcaller
dcb942d24d 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 <JSObject>
    1: decodeString [0x2dd385fb5d1] [/node_modules/socket.io-parser/index.js:~276] [pc=0xf59746881be](this=0x175d34c42b69 <JSGlobal Object>,0x14eccff10fe1 <Very long string[69999990]>)
    2: add [0x31fc2693da29] [/node_modules/socket.io-parser/index.js:242] [bytecode=0xa7ed6554889 offset=11](this=0x0a2881be5069 <Decoder map = 0x3ceaa8bf48c9>,0x14eccff10fe1 <Very...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 0xa09830 node::Abort() [node]
 2: 0xa09c55 node::OnFatalError(char const*, char const*) [node]
 3: 0xb7d71e v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
 4: 0xb7da99 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
 5: 0xd2a1f5  [node]
 6: 0xd2a886 v8::internal::Heap::RecomputeLimits(v8::internal::GarbageCollector) [node]
 7: 0xd37105 v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [node]
 8: 0xd37fb5 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node]
 9: 0xd3965f v8::internal::Heap::HandleGCRequest() [node]
10: 0xce8395 v8::internal::StackGuard::HandleInterrupts() [node]
11: 0x1042cb6 v8::internal::Runtime_StackGuard(int, unsigned long*, v8::internal::Isolate*) [node]
12: 0x13c5b79  [node]
```
2020-05-13 07:37:32 +02:00
Damien Arrachequesne
a5d04354e6 test: transpile to es5 with babelify 2020-05-13 07:23:37 +02:00
Damien Arrachequesne
652402a856 [chore] Release 3.4.0
The build failure is due to some ES6 usage in the debug dependency, which will have to be fixed
in the future (by using Babel for example).

Diff: https://github.com/socketio/socket.io-parser/compare/3.3.0...3.4.0
2019-09-20 11:00:03 +02:00
Dimitar Nestorov
9b3572ea23 [chore] Bump debug to version 4.1.0 (#92) 2019-09-20 10:51:26 +02:00
JinHyuk Kim
de1fd36dc9 [docs] Fix incorrect socket.io-protocol version in Readme (#89)
Ref: https://github.com/socketio/socket.io-protocol
2018-11-19 22:31:13 +01:00
8 changed files with 1403 additions and 117 deletions

View File

@@ -3,7 +3,7 @@ name: CI
on:
push:
branches:
- 'socket.io-parser/3.3.x'
- 'socket.io-parser/3.4.x'
permissions:
contents: read

View File

@@ -1,22 +0,0 @@
language: node_js
sudo: false
node_js:
- '8'
- '10'
git:
depth: 1
matrix:
include:
- node_js: 10
env: BROWSERS=1
cache:
directories:
- node_modules
env:
global:
- secure: >-
Ea4P/R9UlWzDlHSP5ynmLiD/YgLjecIvCviOcRTle9mV3P1j2k94Ay1LVu1Jw4whlNmWLq2Z/p8M63L92ODPMlarPsuME8HlP4zGr41whFhRbFdda4k3zrHfUhZBlnhY1MVWXTtVm/l7DOzpBrNh+wKecxZB3yyyEaA+PSG3qcQ=
- secure: >-
JmPf38qx5Rb6K+WYOMwb5YmESkDmVJ6tgggiJIuyRfHsgQVOO7XBwZuspIKGTSFolUIMaqwQe79Kd+Ehs2ZZ/0lUyF2/6xW3FqFnASUusYJcZdfRjypmBFWs6BRdtEORM8HL0dgBx4O4u/e4ZvtygumbPahjQbMDaqN+MvlpjD0=
- secure: >-
c3pnLhy3VDJqMl16ABA+8vt3I623aNa2wkLceLXb2V1Dc6eiZeulDH2ekwmdVo/r2WwGIKP3Y6B0mq/xP4W0hg4uT+xWh0AmFHclVyM/yp/AqfXrDUv17Vm0vB7OIgp332OiAlK6Dr13YDbWW8iZxmID41O2+2qohLGPn5JMncg=

View File

@@ -1,37 +1,33 @@
## [3.3.5](https://github.com/socketio/socket.io-parser/compare/3.3.4...3.3.5) (2026-03-17)
## [3.4.4](https://github.com/socketio/socket.io-parser/compare/3.4.3...3.4.4) (2026-03-17)
### Bug Fixes
* add a limit to the number of binary attachments ([9d39f1f](https://github.com/socketio/socket.io/commit/9d39f1f080510f036782f2177fac701cc041faaf))
* add a limit to the number of binary attachments ([719f9eb](https://github.com/socketio/socket.io/commit/719f9ebab0772ffb882bd614b387e585c1aa75d4))
## [3.3.4](https://github.com/Automattic/socket.io-parser/compare/3.3.3...3.3.4) (2024-07-22)
## [3.4.3](https://github.com/socketio/socket.io-parser/compare/3.4.2...3.4.3) (2023-05-22)
### Bug Fixes
* check the format of the event name ([#125](https://github.com/Automattic/socket.io-parser/issues/125)) ([ee00660](https://github.com/Automattic/socket.io-parser/commit/ee006607495eca4ec7262ad080dd3a91439a5ba4))
* check the format of the event name ([2dc3c92](https://github.com/socketio/socket.io-parser/commit/2dc3c92622dad113b8676be06f23b1ed46b02ced))
## [3.3.3](https://github.com/Automattic/socket.io-parser/compare/3.3.2...3.3.3) (2022-11-09)
## [3.4.2](https://github.com/socketio/socket.io-parser/compare/3.4.1...3.4.2) (2022-11-09)
### Bug Fixes
* check the format of the index of each attachment ([fb21e42](https://github.com/Automattic/socket.io-parser/commit/fb21e422fc193b34347395a33e0f625bebc09983))
* check the format of the index of each attachment ([04d23ce](https://github.com/socketio/socket.io-parser/commit/04d23cecafe1b859fb03e0cbf6ba3b74dff56d14))
## [3.3.2](https://github.com/Automattic/socket.io-parser/compare/3.3.1...3.3.2) (2021-01-09)
## [3.4.1](https://github.com/socketio/socket.io-parser/compare/3.4.0...3.4.1) (2020-05-13)
### 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)
* prevent DoS (OOM) via massive packets ([#95](https://github.com/socketio/socket.io-parser/issues/95)) ([dcb942d](https://github.com/socketio/socket.io-parser/commit/dcb942d24db97162ad16a67c2a0cf30875342d55))

View File

@@ -4,7 +4,7 @@
[![Build Status](https://secure.travis-ci.org/socketio/socket.io-parser.svg?branch=master)](http://travis-ci.org/socketio/socket.io-parser)
[![NPM version](https://badge.fury.io/js/socket.io-parser.svg)](http://badge.fury.io/js/socket.io-parser)
A socket.io encoder and decoder written in JavaScript complying with version `3`
A socket.io encoder and decoder written in JavaScript complying with version `4`
of [socket.io-protocol](https://github.com/socketio/socket.io-protocol).
Used by [socket.io](https://github.com/automattic/socket.io) and
[socket.io-client](https://github.com/automattic/socket.io-client).

View File

@@ -272,26 +272,6 @@ Decoder.prototype.add = function(obj) {
}
};
function isPayloadValid(type, payload) {
switch (type) {
case 0: // CONNECT
return typeof payload === "object";
case 1: // DISCONNECT
return payload === undefined;
case 4: // ERROR
return typeof payload === "string" || typeof payload === "object";
case 2: // EVENT
case 5: // BINARY_EVENT
return (
isArray(payload) &&
(typeof payload[0] === "string" || typeof payload[0] === "number")
);
case 3: // ACK
case 6: // BINARY_ACK
return isArray(payload);
}
}
/**
* Decode a packet String (JSON data)
*
@@ -379,6 +359,26 @@ function tryParse(str) {
}
}
function isPayloadValid(type, payload) {
switch (type) {
case 0: // CONNECT
return typeof payload === "object";
case 1: // DISCONNECT
return payload === undefined;
case 4: // ERROR
return typeof payload === "string" || typeof payload === "object";
case 2: // EVENT
case 5: // BINARY_EVENT
return (
isArray(payload) &&
(typeof payload[0] === "string" || typeof payload[0] === "number")
);
case 3: // ACK
case 6: // BINARY_ACK
return isArray(payload);
}
}
/**
* Deallocates a parser's resources
*

1410
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "socket.io-parser",
"version": "3.3.5",
"version": "3.4.4",
"description": "socket.io protocol parser",
"repository": {
"type": "git",
@@ -12,11 +12,14 @@
"is-buffer.js"
],
"dependencies": {
"component-emitter": "~1.3.0",
"debug": "~3.1.0",
"debug": "~4.1.0",
"component-emitter": "1.2.1",
"isarray": "2.0.1"
},
"devDependencies": {
"@babel/core": "~7.9.6",
"@babel/preset-env": "~7.9.6",
"babelify": "~10.0.0",
"benchmark": "2.1.2",
"expect.js": "0.3.1",
"mocha": "3.2.0",
@@ -27,5 +30,8 @@
"scripts": {
"test": "make test"
},
"license": "MIT"
"license": "MIT",
"engines": {
"node": ">=10.0.0"
}
}

View File

@@ -23,6 +23,16 @@ if (process.env.CI === 'true') {
type: 'ngrok',
bind_tls: true
};
zuulConfig.browserify = [
{
transform: {
name: "babelify",
presets: ["@babel/preset-env"],
global: true,
only: [ /\/node_modules\/debug\// ]
}
}
]
}
var isPullRequest = process.env.TRAVIS_PULL_REQUEST && process.env.TRAVIS_PULL_REQUEST !== 'false';