hapi-plugin-websocket icon indicating copy to clipboard operation
hapi-plugin-websocket copied to clipboard

Incompatible Auth Heuristics

Open computerpunc opened this issue 6 years ago • 0 comments

hapi is an HTTP server implementation. hapi-plugin-websocket tries to implement WebSocket support over this implementation. In regarding to auth, the current heuristics doesn't follow WebSocket practices.

A native WebSocket server handles auth in the following way:

  1. Receive an HTTP request to upgrade connection to WS. In this request, the server checks auth requirements.
  2. If the request passes auth requirements, the server opens a WS connection.
  3. If the request doesn't pass auth requirements, the server sends an HTTP error response (401, 403, etc.).
  4. No need for any more auth checking on the opened WS connection (except for the handshake keys when opening the connection which the server does automatically).

In hapi-plugin-websocket, the following heuristics for auth is provided:

  1. An HTTP request to upgrade to WS connection is always accepted (unless 404). I.e., a WS connection is always opened, and options.plugins.websocket.connect is always called.
  2. Each time a data packet over the WS connection is received, prior to calling the handler, auth is checked. The auth is basically checked against the original HTTP upgrade request over and over again. Since the input is the same, each check results in the same conclusion (and hence redundant).

Not only that this heuristics don't follow the conventional WebSocket way, but it does introduce problems, such as:

  1. Client are not notified in the standard WS/HTTP way of auth problems via 401, 403 responses.
  2. Handling out of order of packets. Let's say that over an WS connection P1, P2, P3 are sent. If P2 is handled a bit slower by an async auth method than the handling of P1 and P3, the handler my get the packets in the order of P1, P3 and P2.

In order to solve these issues

  1. Auth should be called only once.
  2. Move the auth and options.plugins.websocket.connect to new WS.Server({verifyClient}) method.
  3. Add h to options.plugins.websocket.connect method to return errors (not related to auth) in the standard WS/HTTP way.

computerpunc avatar Jun 13 '19 06:06 computerpunc