mirror of
https://github.com/element-hq/synapse.git
synced 2026-09-17 12:25:13 +00:00
Application services that opt in to receiving ephemeral events (`receive_ephemeral: true` in the [registration](https://spec.matrix.org/v1.19/application-service-api/#registration), added in Matrix v1.13 from [MSC2409](https://github.com/matrix-org/matrix-spec-proposals/pull/2409)) are sent the private read receipts (`m.read.private`) of **every** user in the rooms they are interested in — not just their own users. The [Application Service API](https://spec.matrix.org/v1.19/application-service-api/#pushing-ephemeral-data) is explicit about this (*Pushing ephemeral data*, `m.receipt`): > Private read receipts MUST only be sent for users matching one of the application service's namespaces. Normal read receipts and threaded read receipts are always sent. This matches the [Client-Server API](https://spec.matrix.org/v1.19/client-server-api/#private-read-receipts): "Servers MUST NOT send the `m.read.private` receipt to any other user than the one which originally sent it." The restriction to namespaced users is safe because the appservice could learn those receipts anyway by syncing as the user. For everyone else, `m.read.private` exists precisely so that nobody — including bridges and bots in the room — can observe it. For example, take an appservice registered with: ```yaml namespaces: users: - regex: "@_bridge_.*:example\\.org" exclusive: true ``` When `@alice:example.org` (a regular user, not one of the appservice's) and `@_bridge_bob:example.org` (a namespaced user) each send read receipts in a bridged room, the appservice receives: ```json { "type": "m.receipt", "room_id": "!room:example.org", "content": { "$event": { "m.read": { "@alice:example.org": { "ts": 1436451550453 } }, "m.read.private": { "@_bridge_bob:example.org": { "ts": 1436451550453 }, "@alice:example.org": { "ts": 1436451550453 } } } } } ``` - `m.read` from `@alice` — correct, public read receipts are always sent. - `m.read.private` from `@_bridge_bob` — correct, the user is within the appservice's namespaces. - `m.read.private` from `@alice` — **the leak**: their private read receipt must not be sent to the appservice. ## History - matrix-org/synapse#8437 (Oct 2020, Synapse 1.22.0) implemented MSC2409 ephemeral event delivery to appservices. No leak at that point: private read receipts did not exist yet. - matrix-org/synapse#10413 (Jul 2021, Synapse 1.40.0) added the initial, experimental-flag-gated implementation of MSC2285 ("hidden" read receipts) and filtered them out of the `/sync` path (`filter_out_hidden`) — but not out of the appservice path in the same file. This is where the leak originates, for servers with `msc2285_enabled`. - matrix-org/synapse#12168 (May 2022, Synapse 1.59.0) reworked this into the `m.read.private` receipt type and `filter_out_private_receipts`; the appservice path was again left unfiltered. - matrix-org/synapse#13273 (Aug 2022, Synapse 1.65.0) moved to the stable `m.read.private` identifier; the appservice path has leaked it ever since. --- ### Pull Request Checklist <!-- Please read https://element-hq.github.io/synapse/latest/development/contributing_guide.html before submitting your pull request --> * [x] Pull request is based on the develop branch * [x] Pull request includes a [changelog file](https://element-hq.github.io/synapse/latest/development/contributing_guide.html#changelog). The entry should: - Be a short description of your change which makes sense to users. "Fixed a bug that prevented receiving messages from other servers." instead of "Moved X method from `EventStore` to `EventWorkerStore`.". - Use markdown where necessary, mostly for `code blocks`. - End with either a period (.) or an exclamation mark (!). - Start with a capital letter. - Feel free to credit yourself, by adding a sentence "Contributed by @github_username." or "Contributed by [Your Name]." to the end of the entry. * [x] [Code style](https://element-hq.github.io/synapse/latest/code_style.html) is correct (run the [linters](https://element-hq.github.io/synapse/latest/development/contributing_guide.html#run-the-linters))