Fix unhandled error on HTTP2 upgrade #658
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The kind of change this PR does introduce
Current behaviour
If you send an HTTP2 upgrade request to the server, we catch the
upgrade
event and close the socket when it turns out not to be a websocket upgrade request. In some cases, this leads to anerror
event, which in turn causes the server to crash.I created a bare bones project that demonstrates this problem: https://github.com/jonathanneve/socketiotest
Run the server locally (https://github.com/jonathanneve/socketiotest/blob/main/index.js) and then test it using the included python test case (https://github.com/jonathanneve/socketiotest/blob/main/test.py). The server should crash.
This is the same issue as described here: socketio/socket.io#3564
New behaviour
The
error
event is caught and (in debug mode) logged to the console. This prevents the error from bubbling up and causing the server to crash.Other information (e.g. related issues)
Note that in my situation, the intention is not actually to use HTTP2: I came across the issue by running a vulnerability scanner (Nessus) against my app, which caused it to crash. On closer examination, I found that Nessus was sending an HTTP2 upgrade request. The goal of this PR is not to handle HTTP2, but simply to harden the app, in that a simple upgrade request should not cause a crash.
Note also that I was not able to reproduce the issue using a Node client, as I have less control over the socket options in Node, which is why I used Python for the test case. Using the Nessus scanner (as opposed to my test case), I found that the app crashes only with certain versions of Node (older than v16.16.0), which suggests that the error is contingent on the exact behavior of the socket, which presumably has changed in different Node versions. Either way though, this PR addresses the error in all cases, since it catches any error that occurs while closing the socket.