Skip to content

Buffer vulnerability

Choose a tag to compare
@3rd-Eden 3rd-Eden released this 04 Jan 12:53
· 1006 commits to master since this release

There has been vulnerability in the ping functionality of the ws module which allowed clients to allocate memory by simply 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 we always transform all data that we need to send to a Buffer instance and this is where the problem was. We didn't do any checks for the type of data we were 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 when the server would receive a ping message of 1000 it would allocate 1000 bytes on the server and returned non-zeroed buffer to the client instead of the actual 100 message.

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 makes the server return a non-zeroed buffer of 50 bytes

  client.on('pong', function (data) {
    console.log('got pong')
    console.log(data) // a non-zeroed out allocated buffer returned from the server

As you can imagine that is pretty darn dangerous so we fixed it as soon as we received a heads up about this. So I would like to thank @feross and @mafintosh for discovering this vulnerability and disclosing it to me so it could be resolved asap.