Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: websockets/ws
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 6.2.1
Choose a base ref
...
head repository: websockets/ws
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 6.2.3
Choose a head ref
  • 4 commits
  • 3 files changed
  • 1 contributor

Commits on Jun 1, 2021

  1. [security] Fix ReDoS vulnerability

    A specially crafted value of the `Sec-Websocket-Protocol` header could
    be used to significantly slow down a ws server.
    
    PoC and fix were sent privately by Robert McLaughlin from University of
    California, Santa Barbara.
    lpinca committed Jun 1, 2021
    Copy the full SHA
    78c676d View commit details
  2. [dist] 6.2.2

    lpinca committed Jun 1, 2021
    2
    Copy the full SHA
    9bdb580 View commit details

Commits on Jun 16, 2024

  1. [security] Fix crash when the Upgrade header cannot be read (#2231)

    It is possible that the Upgrade header is correctly received and handled
    (the `'upgrade'` event is emitted) without its value being returned to
    the user. This can happen if the number of received headers exceed the
    `server.maxHeadersCount` or `request.maxHeadersCount` threshold. In this
    case `incomingMessage.headers.upgrade` may not be set.
    
    Handle the case correctly and abort the handshake.
    
    Fixes #2230
    lpinca committed Jun 16, 2024
    Copy the full SHA
    eeb76d3 View commit details
  2. [dist] 6.2.3

    lpinca committed Jun 16, 2024
    Copy the full SHA
    d87f3b6 View commit details
Showing with 58 additions and 3 deletions.
  1. +16 −2 lib/websocket-server.js
  2. +1 −1 package.json
  3. +41 −0 test/websocket-server.test.js
18 changes: 16 additions & 2 deletions lib/websocket-server.js
Original file line number Diff line number Diff line change
@@ -186,12 +186,14 @@ class WebSocketServer extends EventEmitter {
req.headers['sec-websocket-key'] !== undefined
? req.headers['sec-websocket-key'].trim()
: false;
const upgrade = req.headers.upgrade;
const version = +req.headers['sec-websocket-version'];
const extensions = {};

if (
req.method !== 'GET' ||
req.headers.upgrade.toLowerCase() !== 'websocket' ||
upgrade === undefined ||
upgrade.toLowerCase() !== 'websocket' ||
!key ||
!keyRegex.test(key) ||
(version !== 8 && version !== 13) ||
@@ -280,7 +282,7 @@ class WebSocketServer extends EventEmitter {
var protocol = req.headers['sec-websocket-protocol'];

if (protocol) {
protocol = protocol.trim().split(/ *, */);
protocol = protocol.split(',').map(trim);

//
// Optionally call external protocol selection handler.
@@ -399,3 +401,15 @@ function abortHandshake(socket, code, message, headers) {
socket.removeListener('error', socketOnError);
socket.destroy();
}

/**
* Remove whitespace characters from both ends of a string.
*
* @param {String} str The string
* @return {String} A new string representing `str` stripped of whitespace
* characters from both its beginning and end
* @private
*/
function trim(str) {
return str.trim();
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ws",
"version": "6.2.1",
"version": "6.2.3",
"description": "Simple to use, blazing fast and thoroughly tested websocket client and server for Node.js",
"keywords": [
"HyBi",
41 changes: 41 additions & 0 deletions test/websocket-server.test.js
Original file line number Diff line number Diff line change
@@ -383,6 +383,47 @@ describe('WebSocketServer', () => {
});

describe('Connection establishing', () => {
it('fails if the Upgrade header field value cannot be read', (done) => {
const server = http.createServer();
const wss = new WebSocket.Server({ noServer: true });

server.maxHeadersCount = 1;

server.on('upgrade', (req, socket, head) => {
assert.deepStrictEqual(req.headers, { foo: 'bar' });
wss.handleUpgrade(req, socket, head, () => {
done(new Error('Unexpected callback invocation'));
});
});

server.listen(() => {
const req = http.get({
port: server.address().port,
headers: {
foo: 'bar',
bar: 'baz',
Connection: 'Upgrade',
Upgrade: 'websocket'
}
});

req.on('response', (res) => {
assert.strictEqual(res.statusCode, 400);

const chunks = [];

res.on('data', (chunk) => {
chunks.push(chunk);
});

res.on('end', () => {
assert.strictEqual(Buffer.concat(chunks).toString(), 'Bad Request');
server.close(done);
});
});
});
});

it('fails if the Sec-WebSocket-Key header is invalid (1/2)', (done) => {
const wss = new WebSocket.Server({ port: 0 }, () => {
const req = http.get({