From 8b4d6a8176db72f5c2420c5a45f0d97d33af049b Mon Sep 17 00:00:00 2001 From: Damien Arrachequesne Date: Fri, 14 Jan 2022 08:13:33 +0100 Subject: [PATCH] fix(uws): handle invalid websocket upgrades When binding to an uWebSockets.js App, there was an unhandled case that could crash the server: ``` curl "http://localhost:3000/engine.io/?EIO=4&transport=websocket" ``` would result in: ``` Error: Returning from a request handler without responding or attaching an abort handler is forbidden! terminate called without an active exception ``` Note: this does not apply to the default server based on ws, because the error was caught elsewhere in the source code. Related: https://github.com/socketio/socket.io/issues/4250 --- lib/server.ts | 7 +++++++ lib/userver.ts | 4 ++++ test/server.js | 5 ----- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/server.ts b/lib/server.ts index c09b2e1d..44ce2ee6 100644 --- a/lib/server.ts +++ b/lib/server.ts @@ -245,6 +245,13 @@ export abstract class BaseServer extends EventEmitter { }); } + if (transport === "websocket" && !upgrade) { + debug("invalid transport upgrade"); + return fn(Server.errors.BAD_REQUEST, { + name: "TRANSPORT_HANDSHAKE_ERROR" + }); + } + if (!this.opts.allowRequest) return fn(); return this.opts.allowRequest(req, (message, success) => { diff --git a/lib/userver.ts b/lib/userver.ts index 76c9a41d..d28b5ff1 100644 --- a/lib/userver.ts +++ b/lib/userver.ts @@ -28,6 +28,10 @@ export class uServer extends BaseServer { req.connection = { remoteAddress: Buffer.from(res.getRemoteAddressAsText()).toString() }; + + res.onAborted(() => { + debug("response has been aborted"); + }); } protected createTransport(transportName, req) { diff --git a/test/server.js b/test/server.js index 05f5d7bf..3aff7c0e 100644 --- a/test/server.js +++ b/test/server.js @@ -603,9 +603,6 @@ describe("server", () => { }); it("should disallow bad requests (handshake error)", function(done) { - if (process.env.EIO_WS_ENGINE === "uws") { - return this.skip(); - } const partialDone = createPartialDone(done, 2); engine = listen( @@ -618,8 +615,6 @@ describe("server", () => { expect(err.code).to.be(3); expect(err.message).to.be("Bad request"); expect(err.context.name).to.be("TRANSPORT_HANDSHAKE_ERROR"); - expect(err.context.error).to.be.an(Error); - expect(err.context.error.name).to.be("TypeError"); partialDone(); });