Commit Graph

139 Commits

Author SHA1 Message Date
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
Damien Arrachequesne
0de72b9cc2 [chore] Release 3.3.0 2018-11-07 23:58:21 +01:00
Damien Arrachequesne
b47efb270d [fix] Remove any reference to the global variable
Related: https://github.com/socketio/socket.io-client/issues/1166
2018-11-07 23:31:49 +01:00
Damien Arrachequesne
d95e38f6b6 [chore] Update the Makefile 2018-11-07 23:16:54 +01:00
Damien Arrachequesne
b57e06304e [test] Update travis configuration 2018-11-07 23:15:29 +01:00
JinHyuk Kim
48f340ec12 [refactor] Fix a small typo and code styling (#88) 2018-11-07 22:53:25 +01:00
Damien Arrachequesne
6e400188be [chore] Release 3.2.0 2018-02-28 22:08:38 +01:00
Damien Arrachequesne
92c530da47 [fix] Properly handle JSON.stringify errors (#84)
JSON.stringify method throws when passed a circular object.
2018-02-28 22:07:33 +01:00
Damien Arrachequesne
dc4f475a45 [revert] Move binary detection to the parser
So that we can skip the binary check.
2018-02-28 21:55:26 +01:00
Damien Arrachequesne
f115039068 [test] Update travis configuration 2018-02-28 21:19:36 +01:00
Damien Arrachequesne
6b356eb4f0 [fix] Properly detect typed arrays (#85)
ArrayBuffer.isView method is not defined in IE10.
2018-02-28 21:18:16 +01:00
Damien Arrachequesne
f9c06255de [chore] Release 3.1.3 2018-02-25 09:20:05 +01:00
Damien Arrachequesne
f0a7df1059 [fix] Ensure packet data is an array (#83)
Related: https://github.com/socketio/socket.io/pull/3140
2018-02-25 09:05:16 +01:00
Damien Arrachequesne
88225783f7 [fix] Use ArrayBuffer.isView to check for typed arrays (#82) 2018-02-25 09:04:02 +01:00
Damien Arrachequesne
dd164e6a5f [chore] Bump debug to version 3.1.0 2018-02-18 11:50:26 +01:00
Damien Arrachequesne
f9c3549dd1 [chore] Release 3.1.2 2017-04-27 23:46:00 +02:00
Damien Arrachequesne
425391ace9 [chore] Bump has-binary2 to version 1.0.2 (#70) 2017-04-27 23:06:57 +02:00
Damien Arrachequesne
b4f849a6fe [fix] Fix Blob detection for iOS 8/9 (#69) 2017-04-26 21:43:22 +02:00
Damien Arrachequesne
eaee5d58c4 [chore] Release 3.1.1 2017-04-25 00:22:17 +02:00
Damien Arrachequesne
2f31a4e8f7 [fix] Ensure globals are functions before running instanceof (#68)
Following https://github.com/socketio/has-binary/pull/4.
2017-04-25 00:21:17 +02:00
Damien Arrachequesne
8e5465de2f [chore] Release 3.1.0 2017-04-24 23:33:46 +02:00
Damien Arrachequesne
403b858a8d [chore] Bump debug to version 2.6.4 (#67) 2017-04-24 23:32:13 +02:00
Damien Arrachequesne
f44256c523 [feat] Move binary detection to the parser (#66) 2017-04-24 23:20:51 +02:00
Damien Arrachequesne
817adca41d [chore] Release 3.0.0 2017-04-03 23:51:53 +02:00
Damien Arrachequesne
e295b9b1c2 [chore] Bump isarray to version 2.0.1 (#65) 2017-04-03 23:48:59 +02:00
Jimmy Karl Roland Wärting
e39f5a8c6a [chore] Use native JSON and drop support for older nodejs versions (#64) 2017-04-03 23:15:24 +02:00
Damien Arrachequesne
9ce9a98dd0 [chore] Release 2.3.2 (#59) 2016-12-30 22:43:07 +01:00
Gatsbill
2314c10f4f [perf] Small optimisations (#57) 2016-12-30 22:25:49 +01:00
Damien Arrachequesne
5ac691e7e4 [chore] Update zuul config to speed up tests in browser (#58) 2016-12-30 17:54:42 +01:00
Damien Arrachequesne
c2d0a08d7f [refactor] Remove useless variable (#55) 2016-12-17 03:34:00 +01:00
Damien Arrachequesne
aed82572ba [chore] Bump dependencies (#56)
- bump debug to version 2.3.3
- bump component-emitter to version 1.2.1
- bump benchmark to version 2.1.2
- bump expect.js to version 0.3.1
- bump mocha to version 3.2.0
- bump zuul to version 3.11.1
2016-12-17 03:33:44 +01:00
Gatsbill
9072faa1e1 [refactor] Remove unused var (#53) 2016-12-17 02:33:05 +01:00
Gatsbill
97721957b9 [refactor] Use strict equality when possible (#52) 2016-12-17 02:32:21 +01:00
Damien Arrachequesne
64455b432c [chore] Release 2.3.1 (#51) 2016-10-24 02:31:53 +02:00
Damien Arrachequesne
0e2dcb7281 [chore] Revert "Remove deprecated isarray dependency" (#50)
The fallback is needed for IE6, IE7 and IE8.
2016-10-24 02:29:22 +02:00
Damien Arrachequesne
baf384cd6c [chore] Release 2.3.0 (#49) 2016-10-21 01:32:51 +02:00
Damien Arrachequesne
972d0aa93c [chore] Move benchmark to dev dependencies (#48) 2016-10-21 01:10:04 +02:00
Tom Atkinson
9b479bcee6 [perf] Split try catch into separate function (#40) 2016-10-21 01:07:30 +02:00