|
| 1 | +# MSC4311: Ensuring the create event is available on invites |
| 2 | + |
| 3 | +Historically, when processing an incoming invite or outgoing knock, safety tooling would parse the room ID despite |
| 4 | +[being opaque](https://spec.matrix.org/v1.15/appendices/#room-ids), to determine the server which |
| 5 | +originally created the room. If that server was considered abusive, the invite or |
| 6 | +knock may be rejected or blocked early by the tooling. Note that checking the domain of the |
| 7 | +sender of an invite is inadequate, because the sender may not be on the same server as the |
| 8 | +user who created the room. |
| 9 | + |
| 10 | +With [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291), room IDs lose their |
| 11 | +domain component. This, combined with [Stripped State](https://spec.matrix.org/v1.15/client-server-api/#stripped-state) |
| 12 | +recommending rather than requiring the `m.room.create` event, makes the above check harder if not |
| 13 | +impossible when the create event is missing or incomplete, as the room ID cannot be confirmed in |
| 14 | +MSC4291+ room versions. |
| 15 | + |
| 16 | +To mitigate the problem in the case of invites, |
| 17 | +this MSC shifts the `m.room.create` event to a *required* stripped state event, and imposes validation |
| 18 | +to ensure the event matches the room. To support the new validation, the `m.room.create` event must |
| 19 | +be formatted as a full PDU in the stripped state of [invites](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1inviteroomideventid) |
| 20 | +over federation. Similar treatment is applied to other stripped state events for uniformity. |
| 21 | + |
| 22 | +[Knocks](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1send_knockroomideventid) |
| 23 | +additionally include the full PDU format, though only to ensure symmetry between the two instances of |
| 24 | +stripped state. It's not possible to prevent a knock based on stripped state because the server will |
| 25 | +have already sent the knock before stripped state is received. |
| 26 | + |
| 27 | + |
| 28 | +## Proposal |
| 29 | + |
| 30 | +On the Client-Server API, `m.room.create` MUST be provided in [Stripped State](https://spec.matrix.org/v1.15/client-server-api/#stripped-state), |
| 31 | +where available. No other changes are proposed to the Client-Server API. For clarity, this means clients |
| 32 | +continue to receive events which only have `content`, `sender`, `state_key` (optional), and `type` in |
| 33 | +the `invite_room_state`, `knock_room_state`, and wherever else stripped state is used. |
| 34 | + |
| 35 | +Over federation, servers MUST include the `m.room.create` event in the [`invite_room_state`](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1inviteroomideventid) |
| 36 | +and [`knock_room_state`](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1send_knockroomideventid). |
| 37 | +Servers MUST additionally format events in `invite_room_state` and `knock_room_state` as PDUs according |
| 38 | +to that room version's event format specification. Together, these changes allow servers to validate |
| 39 | +the room ID matches the invite (or knock, though it's already sent by the time validation would happen). |
| 40 | + |
| 41 | +Specifically, including the `m.room.create` event as a full PDU allows servers to calculate the room |
| 42 | +ID by hashing the event in MSC4291+ room versions. For other room versions (1 through 11), the server |
| 43 | +can at most compare the `room_id` field of the create event with the invite/knock membership event. |
| 44 | + |
| 45 | +If any of the events are not a PDU, not for the room ID specified, or fail [signature checks](https://spec.matrix.org/v1.15/server-server-api/#validating-hashes-and-signatures-on-received-events), |
| 46 | +or the `m.room.create` event is missing, the receiving server MAY respond to invites with a `400 M_MISSING_PARAM` |
| 47 | +standard Matrix error (new to the endpoint). For invites to room version 12+ rooms, servers SHOULD |
| 48 | +rather than MAY respond to such requests with `400 M_MISSING_PARAM`. For knocks, the server SHOULD remove any events from |
| 49 | +`knock_room_state` which fail the same validation check before passing the details along to clients. |
| 50 | +Ideally, the server would be able to prevent the knock from happening, though by the time the server |
| 51 | +can see the `knock_room_state`, the knock has already happened. |
| 52 | + |
| 53 | +**Note**: Servers SHOULD consider their local ecosystems before imposing this validation completely, |
| 54 | +per the "Migration" section later in this document. |
| 55 | + |
| 56 | +The `400 M_MISSING_PARAM` error SHOULD be translated to a 5xx error by the sending server over the |
| 57 | +Client-Server API. This is done because there's nothing the client can materially do differently to |
| 58 | +make the request succeed. |
| 59 | + |
| 60 | +When comparing the room IDs, servers will need to calculate the room ID from the `m.room.create` event |
| 61 | +as described by MSC4291 (take the reference hash of the event for an event ID, swap the sigil). |
| 62 | + |
| 63 | + |
| 64 | +## Potential issues |
| 65 | + |
| 66 | +* Some server implementations allow safety tooling and other applications to hook into them between |
| 67 | + the Federation API and Client-Server API. Such implementations are encouraged to make the create |
| 68 | + event reasonably available in its full form to those applications. Typically, this will be an internal |
| 69 | + representation of the event which still has the capability to serialize down to a PDU. |
| 70 | + |
| 71 | +* Implementations should take care to not unintentionally trust the events contained in `invite_room_state` |
| 72 | + and `knock_room_state`, despite appearing as complete events. This is due to the lack of each event's |
| 73 | + auth chain being included, and reassurance that the events are the current events. |
| 74 | + |
| 75 | +## Alternatives |
| 76 | + |
| 77 | +This proposal fills a potential gap in information created by MSC4291, making the alternatives roughly |
| 78 | +equivalent to "don't do this". A possible alternative is in the shape of [MSC4329](https://github.com/matrix-org/matrix-spec-proposals/pull/4329) |
| 79 | +where the `/invite` endpoint changes, however the changes are roughly the same as this proposal's. |
| 80 | + |
| 81 | + |
| 82 | +## Security considerations |
| 83 | + |
| 84 | +Security considerations are made throughout, especially around validating the events included. |
| 85 | + |
| 86 | + |
| 87 | +## Unstable prefix |
| 88 | + |
| 89 | +This proposal does not require an unstable prefix as the behaviour can be accomplished without overly |
| 90 | +affecting client or server implementations. |
| 91 | + |
| 92 | + |
| 93 | +## Migration |
| 94 | + |
| 95 | +Mentioned above, existing server implementations SHOULD warn rather than fail on invites which don't |
| 96 | +have complete PDUs inside `invite_room_state` until their local ecosystem adoption allows for the |
| 97 | +full set of validation to be applied. If PDUs are complete, but for a different room, the invite SHOULD |
| 98 | +still fail in v12 rooms per the validation above. |
| 99 | + |
| 100 | +This proposal suggests that servers wait no longer than 3 months (or about 1 full spec release cycle) |
| 101 | +after this proposal is released to enforce the full validation, though servers may extend this as |
| 102 | +needed for their ecosystems to gain support. |
| 103 | + |
| 104 | + |
| 105 | +## Dependencies |
| 106 | + |
| 107 | +This proposal requires [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291) in |
| 108 | +order to make any amount of sense. |
0 commit comments