Skip to content

Commit

Permalink
fix(websocket): validate payload length received (nodejs#1822)
Browse files Browse the repository at this point in the history
  • Loading branch information
KhafraDev authored and anonrig committed Apr 4, 2023
1 parent 984b898 commit 42f8afe
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
12 changes: 12 additions & 0 deletions lib/websocket/receiver.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,18 @@ class ByteParser extends Writable {

const buffer = this.consume(8)
const upper = buffer.readUInt32BE(0)

// 2^31 is the maxinimum bytes an arraybuffer can contain
// on 32-bit systems. Although, on 64-bit systems, this is
// 2^53-1 bytes.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_array_length
// https://source.chromium.org/chromium/chromium/src/+/main:v8/src/common/globals.h;drc=1946212ac0100668f14eb9e2843bdd846e510a1e;bpv=1;bpt=1;l=1275
// https://source.chromium.org/chromium/chromium/src/+/main:v8/src/objects/js-array-buffer.h;l=34;drc=1946212ac0100668f14eb9e2843bdd846e510a1e
if (upper > 2 ** 31 - 1) {
failWebsocketConnection(this.ws, 'Received payload length > 2^31 bytes.')
return
}

const lower = buffer.readUInt32BE(4)

this.#info.payloadLength = (upper << 8) + lower
Expand Down
30 changes: 30 additions & 0 deletions test/websocket/receive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use strict'

const { test } = require('tap')
const { WebSocketServer } = require('ws')
const { WebSocket } = require('../..')

test('Receiving a frame with a payload length > 2^31-1 bytes', (t) => {
t.plan(1)

const server = new WebSocketServer({ port: 0 })

server.on('connection', (ws) => {
const socket = ws._socket

socket.write(Buffer.from([0x81, 0x7F, 0xCA, 0xE5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00]))
})

const ws = new WebSocket(`ws://localhost:${server.address().port}`)

t.teardown(() => {
ws.close()
server.close()
})

ws.onmessage = t.fail

ws.addEventListener('error', (event) => {
t.type(event.error, Error) // error event is emitted
})
})

0 comments on commit 42f8afe

Please sign in to comment.