Skip to content

Instantly share code, notes, and snippets.

Last active November 20, 2017 01:44
Show Gist options
  • Save c0nrad/e92005446c480707a74a to your computer and use it in GitHub Desktop.
Save c0nrad/e92005446c480707a74a to your computer and use it in GitHub Desktop.


@nodesecurity @feross @mafintosh


The writeup implies that the websocket server will receive the number 50, and by type confusion accidentally allocate an uninitialized buffer of size 50. The buffer will then be sent to the client as the pong response. Using this bug, a malicious actor can potentially read memory off vulnerable servers.

But, after playing around with the PoC, I don’t think this is correct. I think the actual problem is in the client. If you track down, you’ll see that calling actually allocates the buffer and sends it to the server. So the server is simply responding with the clients memory buffer. The server never allocates 50 bytes of uninitialized memory and sends it back to the client. It's doing exactly what it should be doing.

To prove this, we're going to print out exactly what the client is sending, and what the server receives.


Using ws: "1.0.0"

Server PoC:

var ws = require('ws').Server;

var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({ port: 8085 });

wss.on('connection', function connection(ws) {
  ws.on('message', function incoming(message) {
    console.log('received: %s', message);


console.log("websocket server listening on :8085")

Client PoC:

var ws = require('ws')

var client = new ws('ws://')

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

Then modify line 647 of the server’s ws package to print out the unmasked data.

Then modify line 158 of the client’s ws package to print out the payload before it is sent to the server.

Running the PoC you should see something similar to: example

This means that the problem was actually in, not the server’s pong response.

The Fix

Even though the advisory is wrong, the fix is still correct.

The fix converts the into essentially‘50’) inside of the sender.


Stuart Larsen, Yahoo Paranoids

Copy link

c0nrad commented Jan 6, 2016

I also attempted to exploit just the server using a golang client implementation. I believe everything server side is coerced to type Buffer. So there was no real vulnerability. (except for clients potentially spewing their memory all over the place).

golang PoC:

Copy link

feross commented Jan 6, 2016

You're correct. The disclosure, as currently written, overstates the severity of the problem.

Still, it's important that this was fixed because it might be possible to get a server to call one of these:


especially if the socket server has some echo functionality:

server.on('connection', function (socket) {
  socket.on('message', function (message) {
    message = JSON.parse(message)
    if (message.type === 'echo') {

socket.send(number) called on the server, will disclose server memory.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment