Remote Memory Disclosure

Module: ws

Published: January 4th, 2016

Reported by: Feross Aboukhadijeh / Mathias Buss



Vulnerable: <= 1.0.0
Patched: >= 1.0.1


UPDATE Jan 6, 2016

Some additional, important details have been made available by Stuart Larsen. The client (which could in fact be the server in certain instances) is that one that allocates and sends the memory that is then echo'd by the server.

A vulnerability was found in the ping functionality of the ws module which allowed clients to allocate memory by sending a ping frame. The ping functionality by default responds with a pong frame and the previously given payload of the ping frame.

This is exactly what you expect, but internally ws always transforms all data that we need to send to a Buffer instance and that is where the vulnerability existed. ws didn't do any checks for the type of data it was sending. With buffers in node when you allocate it when a number instead of a string it will allocate the amount of bytes.

var x = new Buffer(100);
// vs
var x = new Buffer('100');

This would allocate 100 bytes of memory in the first example and just 3 bytes with 100 as value in the second example. So the client would allocate 100 bytes of non-zeroed buffer and send that to the server.

Example POC

var ws = require('ws')

var server = new ws.Server({ port: 9000 })
var client = new ws('ws://localhost:9000')

client.on('open', function () {
  console.log('open') // this sends a non-zeroed buffer of 50 bytes

  client.on('pong', function (data) {
    console.log('got pong')
    console.log(data) // Data from the client. 


Update to version 1.0.1 or greater.


Sign up FREE for
nsp Continuous Security

Free for open source and the first private repo,
then just $1/mo per private repo