Skip to content

Any client can make every presence subscriber on a channel re-send its presence #758

Description

@alecgibson

Summary

A presence request ({a: 'pr', ch}) makes every client subscribed to ch re-send all of its non-null local presence. The server publishes the request without any checks: the requester doesn't need to be subscribed to the channel, and no presence middleware runs for it (Agent._requestPresence, and the receiving agents forward it to their clients in _handlePresenceData without going through 'sendPresence').

Each re-sent presence is then an ordinary submission: it goes through 'receivePresence', a transform to the latest doc version for doc presence, and a broadcast through 'sendPresence' to every other subscriber. So one cheap message costs work that grows with the square of the number of subscribers.

Repro

  1. Subscribe 10 clients to room, each with one presence
  2. From an 11th client that isn't subscribed, send {a: 'pr', ch: 'room'}
  3. The server handles 10 presence submissions and 90 'sendPresence' deliveries

Sending pr in a loop repeats this indefinitely, on any channel, including doc channels for docs the requester can't read.

Suggested fix

Some combination of:

  • Only accept pr from an agent subscribed to that channel. The only client-side caller, RemoteDocPresence, is already subscribed.
  • Throttle re-broadcasts, so a burst of requests on a channel triggers one round of re-sends.
  • Run a middleware hook for presence requests, so apps can gate them.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions