Skip to content

Commit

Permalink
[major] Throw an error if the connection URL is invalid
Browse files Browse the repository at this point in the history
Make the `WebSocket` constructor throw a `SyntaxError` if the URL
contains a fragment identifier or if the URL's protocol is not one of
`'ws:'`, `'wss:'`, or `'ws+unix:'`.
  • Loading branch information
lpinca committed Jul 14, 2021
1 parent 552b506 commit ebea038
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 6 deletions.
24 changes: 19 additions & 5 deletions lib/websocket.js
Original file line number Diff line number Diff line change
Expand Up @@ -613,18 +613,32 @@ function initAsClient(websocket, address, protocols, options) {
parsedUrl = address;
websocket._url = address.href;
} else {
parsedUrl = new URL(address);
try {
parsedUrl = new URL(address);
} catch (e) {
throw new SyntaxError(`Invalid URL: ${address}`);
}

websocket._url = address;
}

const isSecure = parsedUrl.protocol === 'wss:';
const isUnixSocket = parsedUrl.protocol === 'ws+unix:';

if (!parsedUrl.host && (!isUnixSocket || !parsedUrl.pathname)) {
throw new Error(`Invalid URL: ${websocket.url}`);
if (parsedUrl.protocol !== 'ws:' && !isSecure && !isUnixSocket) {
throw new SyntaxError(
'The URL\'s protocol must be one of "ws:", "wss:", or "ws+unix:"'
);
}

if (isUnixSocket && !parsedUrl.pathname) {
throw new SyntaxError("The URL's pathname is empty");
}

if (parsedUrl.hash) {
throw new SyntaxError('The URL contains a fragment identifier');
}

const isSecure =
parsedUrl.protocol === 'wss:' || parsedUrl.protocol === 'https:';
const defaultPort = isSecure ? 443 : 80;
const key = randomBytes(16).toString('base64');
const get = isSecure ? https.get : http.get;
Expand Down
17 changes: 16 additions & 1 deletion test/websocket.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,24 @@ class CustomAgent extends http.Agent {
describe('WebSocket', () => {
describe('#ctor', () => {
it('throws an error when using an invalid url', () => {
assert.throws(
() => new WebSocket('foo'),
/^SyntaxError: Invalid URL: foo$/
);

assert.throws(
() => new WebSocket('https://echo.websocket.org'),
/^SyntaxError: The URL's protocol must be one of "ws:", "wss:", or "ws\+unix:"$/
);

assert.throws(
() => new WebSocket('ws+unix:'),
/^Error: Invalid URL: ws\+unix:$/
/^SyntaxError: The URL's pathname is empty$/
);

assert.throws(
() => new WebSocket('wss://echo.websocket.org#foo'),
/^SyntaxError: The URL contains a fragment identifier$/
);
});

Expand Down

1 comment on commit ebea038

@abratnap
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if someone running websocket over http/s?

Please sign in to comment.