VYPR
Moderate severityNVD Advisory· Published May 27, 2023· Updated Jan 13, 2025

Insufficient validation when decoding a Socket.IO packet

CVE-2023-32695

Description

socket.io parser is a socket.io encoder and decoder written in JavaScript complying with version 5 of socket.io-protocol. A specially crafted Socket.IO packet can trigger an uncaught exception on the Socket.IO server, thus killing the Node.js process. A patch has been released in version 4.2.3.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
socket.io-parsernpm
>= 4.0.4, < 4.2.34.2.3
socket.io-parsernpm
>= 3.4.0, < 3.4.33.4.3
socket.io-parsernpm
< 3.3.43.3.4

Affected products

1

Patches

4
ee006607495e

fix: check the format of the event name (#125)

https://github.com/socketio/socket.io-parserArnau Fugarolas BarbenaJul 22, 2024via ghsa
3 files changed · +38 11
  • index.js+22 3 modified
    @@ -268,6 +268,26 @@ 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)
      *
    @@ -329,11 +349,10 @@ function decodeString(str) {
       // look up json data
       if (str.charAt(++i)) {
         var payload = tryParse(str.substr(i));
    -    var isPayloadValid = payload !== false && (p.type === exports.ERROR || isArray(payload));
    -    if (isPayloadValid) {
    +    if (isPayloadValid(p.type, payload)) {
           p.data = payload;
         } else {
    -      return error('invalid payload');
    +      throw new Error("invalid payload");
         }
       }
     
    
  • test/arraybuffer.js+1 1 modified
    @@ -50,7 +50,7 @@ describe('parser', function() {
       it('cleans itself up on close', function() {
         var packet = {
           type: parser.BINARY_EVENT,
    -      data: [new ArrayBuffer(2), new ArrayBuffer(3)],
    +      data: ["foo", new ArrayBuffer(2), new ArrayBuffer(3)],
           id: 0,
           nsp: '/'
         };
    
  • test/parser.js+15 7 modified
    @@ -86,12 +86,20 @@ describe('parser', function(){
         }
       });
     
    -  it('returns an error packet on parsing error', function(done){
    -    var decoder = new parser.Decoder();
    -    decoder.on('decoded', function(packet) {
    -      expect(packet).to.eql({ type: 4, data: 'parser error: invalid payload' });
    -      done();
    -    });
    -    decoder.add('442["some","data"');
    +  it('returns an error packet on parsing error', function(){
    +    function isInvalidPayload (str) {
    +      expect(function () {
    +        new parser.Decoder().add(str)
    +      }).to.throwException(/^invalid payload$/);
    +    }
    +
    +    isInvalidPayload('442["some","data"');
    +    isInvalidPayload('0/admin,"invalid"');
    +    isInvalidPayload("1/admin,{}");
    +    isInvalidPayload('2/admin,"invalid');
    +    isInvalidPayload("2/admin,{}");
    +    isInvalidPayload('2[{"toString":"foo"}]');
    +    isInvalidPayload('2[true,"foo"]');
    +    isInvalidPayload('2[null,"bar"]');
       });
     });
    
2dc3c92622da

fix: check the format of the event name

https://github.com/socketio/socket.io-parserDamien ArrachequesneMay 22, 2023via ghsa
3 files changed · +38 11
  • index.js+22 3 modified
    @@ -329,11 +329,10 @@ function decodeString(str) {
       // look up json data
       if (str.charAt(++i)) {
         var payload = tryParse(str.substr(i));
    -    var isPayloadValid = payload !== false && (p.type === exports.ERROR || isArray(payload));
    -    if (isPayloadValid) {
    +    if (isPayloadValid(p.type, payload)) {
           p.data = payload;
         } else {
    -      return error('invalid payload');
    +      throw new Error("invalid payload");
         }
       }
     
    @@ -349,6 +348,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
      *
    
  • test/arraybuffer.js+1 1 modified
    @@ -50,7 +50,7 @@ describe('parser', function() {
       it('cleans itself up on close', function() {
         var packet = {
           type: parser.BINARY_EVENT,
    -      data: [new ArrayBuffer(2), new ArrayBuffer(3)],
    +      data: ["foo", new ArrayBuffer(2), new ArrayBuffer(3)],
           id: 0,
           nsp: '/'
         };
    
  • test/parser.js+15 7 modified
    @@ -86,12 +86,20 @@ describe('parser', function(){
         }
       });
     
    -  it('returns an error packet on parsing error', function(done){
    -    var decoder = new parser.Decoder();
    -    decoder.on('decoded', function(packet) {
    -      expect(packet).to.eql({ type: 4, data: 'parser error: invalid payload' });
    -      done();
    -    });
    -    decoder.add('442["some","data"');
    +  it('returns an error packet on parsing error', function(){
    +    function isInvalidPayload (str) {
    +      expect(function () {
    +        new parser.Decoder().add(str)
    +      }).to.throwException(/^invalid payload$/);
    +    }
    +
    +    isInvalidPayload('442["some","data"');
    +    isInvalidPayload('0/admin,"invalid"');
    +    isInvalidPayload("1/admin,{}");
    +    isInvalidPayload('2/admin,"invalid');
    +    isInvalidPayload("2/admin,{}");
    +    isInvalidPayload('2[{"toString":"foo"}]');
    +    isInvalidPayload('2[true,"foo"]');
    +    isInvalidPayload('2[null,"bar"]');
       });
     });
    
3b78117bf6ba

fix: check the format of the event name

https://github.com/socketio/socket.io-parserDamien ArrachequesneMay 22, 2023via ghsa
2 files changed · +7 1
  • lib/index.ts+4 1 modified
    @@ -275,7 +275,10 @@ export class Decoder extends Emitter<{}, {}, DecoderReservedEvents> {
             return typeof payload === "string" || typeof payload === "object";
           case PacketType.EVENT:
           case PacketType.BINARY_EVENT:
    -        return Array.isArray(payload) && payload.length > 0;
    +        return (
    +          Array.isArray(payload) &&
    +          (typeof payload[0] === "string" || typeof payload[0] === "number")
    +        );
           case PacketType.ACK:
           case PacketType.BINARY_ACK:
             return Array.isArray(payload);
    
  • test/parser.js+3 0 modified
    @@ -118,6 +118,9 @@ describe("socket.io-parser", () => {
         isInvalidPayload("1/admin,{}");
         isInvalidPayload('2/admin,"invalid');
         isInvalidPayload("2/admin,{}");
    +    isInvalidPayload('2[{"toString":"foo"}]');
    +    isInvalidPayload('2[true,"foo"]');
    +    isInvalidPayload('2[null,"bar"]');
     
         expect(() => new Decoder().add("999")).to.throwException(
           /^unknown packet type 9$/
    
1c220ddbf45e

fix: allow integers as event names

https://github.com/socketio/socket.io-parserDamien ArrachequesneJan 15, 2021via ghsa
2 files changed · +12 1
  • lib/index.ts+1 1 modified
    @@ -245,7 +245,7 @@ export class Decoder extends Emitter {
             return typeof payload === "string" || typeof payload === "object";
           case PacketType.EVENT:
           case PacketType.BINARY_EVENT:
    -        return Array.isArray(payload) && typeof payload[0] === "string";
    +        return Array.isArray(payload) && payload.length > 0;
           case PacketType.ACK:
           case PacketType.BINARY_ACK:
             return Array.isArray(payload);
    
  • test/parser.js+11 0 modified
    @@ -47,6 +47,17 @@ describe("parser", () => {
         );
       });
     
    +  it("encodes an event (with an integer as event name)", (done) => {
    +    helpers.test(
    +      {
    +        type: PacketType.EVENT,
    +        data: [1, "a", {}],
    +        nsp: "/",
    +      },
    +      done
    +    );
    +  });
    +
       it("encodes an event (with ack)", (done) => {
         helpers.test(
           {
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

8

News mentions

0

No linked articles in our index yet.