Skip to content

Security fix for channel event dispatch

Choose a tag to compare

@github-actions github-actions released this 05 Oct 12:38
· 18 commits to main since this release

This release fixes a security issue in channel event dispatch. A subscribed client could send an event named after a built-in object method, such as valueOf or constructor, and receive the channel instance or its socket in the acknowledgement. The response included channel fields, injected services, socket.user, and socket.raw.data. No @onMessage handler was required. Only events declared with @onMessage are now dispatched. Other event names are rejected with Unknown channel event.

Upgrading is strongly recommended. See GHSA-488x-pgj9-xf2c

Breaking changes

@adonisjs/core 7.6 or newer is now required.

Generated channel manifests now import channels through the #channels/* alias instead of #app/*. The #app/* alias is not defined by the AdonisJS starter kits, so applications failed to boot once they had a channel. node ace configure @rlanz/socket now adds the alias and creates app/channels. Applications configured with 0.2.x must add the alias to package.json:

{
  "imports": {
    "#channels/*": "./app/channels/*.js"
  }
}

If you discover channels from another directory with a local Assembler hook, set the new importAlias option to an alias that points to that directory. Channel sources no longer need to live inside app.

Testing

The provider is now registered in the test environment, so @rlanz/socket/services/main can be imported under node ace test and socket.fake() works as documented. During tests, the provider starts before the HTTP server, logs a warning, and does not start the WebSocket server. Applications configured with 0.2.x should add 'test' to the provider environments in adonisrc.ts:

{
  file: () => import('@rlanz/socket/provider'),
  environment: ['web', 'test'],
}

Client reconnection

Calling disconnect() while an automatic reconnect attempt is in progress now stops reconnecting. Previously, the client scheduled another attempt.

shouldReconnect is now consulted for every failed automatic reconnect attempt. When an attempt fails without a close event, it receives a close event with code 1006. This also works in React Native, which does not provide a global CloseEvent.