The vulnerability is a memory leak in the WebSocket upgrade process of the Hono Node.js server adapter. When a client attempts to upgrade to a WebSocket connection with a missing or malformed Sec-WebSocket-Key header, the underlying 'ws' library aborts the handshake. However, the @hono/node-server adapter did not properly handle this failure scenario.
The core of the issue lies in the setupWebSocket function, which uses a waiterMap to track pending WebSocket connections. For each upgrade request, an entry was added to this map, and a promise was created via waitForWebSocket. In a successful handshake, this entry would be removed. But when the handshake was aborted due to an invalid key, the 'connection' event was never emitted, and no cleanup logic was triggered. The promise remained pending, and the entry in waiterMap, which held a reference to the request object, was never deleted.
An unauthenticated attacker could repeatedly send such malformed upgrade requests to a route using the upgradeWebSocket function. Each request would cause a small amount of memory to be leaked. Over time, this would lead to unbounded memory growth, eventually causing the server to crash, resulting in a Denial of Service (DoS).
The patch addresses this by introducing a rejection path for the promise in waitForWebSocket and adding a 'close' event listener on the underlying socket. If the socket closes before the handshake is complete (which is what happens on an abort), the corresponding promise is rejected, and the entry is cleaned up from the waiterMap, thus plugging the memory leak.