From b7ec690e2c95112d44a3dc40a3a5d5ce61d6b060 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 11 Jul 2025 16:56:07 -0600 Subject: [PATCH 01/17] MSC: Ensuring the create event is available on invites and knocks --- proposals/4311-stripped-state-create-event.md | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 proposals/4311-stripped-state-create-event.md diff --git a/proposals/4311-stripped-state-create-event.md b/proposals/4311-stripped-state-create-event.md new file mode 100644 index 00000000000..b7594edd2c6 --- /dev/null +++ b/proposals/4311-stripped-state-create-event.md @@ -0,0 +1,116 @@ +# MSC4311: Ensuring the create event is available on invites and knocks + +Historically, when processing an invite or knock, safety tooling would parse the room ID despite +[being opaque](https://spec.matrix.org/v1.15/appendices/#room-ids) to determine the server which +originally created the room. If that server was considered abusive, the invite/knock may be rejected +or blocked early by the tooling. This approach is preferred because the user sending the invite may +not be on the same server as the user who created the room, but is often still checked by safety +tooling. + +With [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291), room IDs lose their +domain component, which can make the first check described above harder if not impossible. When +speaking over federation however, [invites](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1inviteroomideventid) +and [knocks](https://spec.matrix.org/v1.15/server-server-api/#get_matrixfederationv1make_knockroomiduserid) +contain a concept of "stripped state events" which give (unsigned) context about the room for the +consuming clients. The Client-Server API [Stripped State](https://spec.matrix.org/v1.15/client-server-api/#stripped-state) +section has more information about what these 'events' are and how they work. + +This MSC aims to reintroduce the accessibility of the creator's server name to clients (and safety +tooling) by requiring the `m.room.create` event *at least* be a full and proper PDU in affected room +versions when transiting the Federation API via stripped state, allowing intermediary servers and +clients to inspect the creator's domain name. + + +## Proposal + +This proposal is split into the Federation API changes and Client-Server API changes for clarity. + + +### Federation API + +For room versions affected by [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291), +the `m.room.create` event MUST be included in [`invite_room_state`](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1inviteroomideventid) +and [`knock_room_state`](https://spec.matrix.org/v1.15/server-server-api/#get_matrixfederationv1make_knockroomiduserid) +and MUST be a properly-formatted PDU according to that room version's event format specification. + +If the `m.room.create` event is not present, not a PDU, or not for the room ID specified, the server +MUST fail to continue processing the invite or knock. For invites, this is a `400 M_MISSING_PARAM` +standard Matrix error (new to the endpoint). For knocks, this means the server drops the `make_knock` +response and never completes a `send_knock`. For both operations, the associated Client-Server API +request is failed with `500 M_BAD_STATE`. A 4xx error isn't used for the Client-Server API because +there's nothing the client can materially do differently to fix that request. + +For room versions *not* affected by MSC4291, servers SHOULD include the properly-formatted `m.room.create` +PDU. This is not made mandatory to avoid a situation where servers trust data that shouldn't be trusted +for the reasons described by MSC4291. + +To determine whether a room is "affected" by MSC4291, servers MUST inspect the `room_id` rather than +the create event's `room_version`. Specifically, a room ID with a domain component is *not* affected +while one without a domain component (and happens to be `!<43 unpadded urlsafe base64 chars>`) *is* +affected. This is done to ensure the server is not potentially confused by a malicious server providing +a create event for a different, unaffected, room. + +When a room is affected, the server MUST validate the `m.room.create` event as follows: + +1. If the event has a `room_id`, reject. +2. If the event does not otherwise comply with the event format for its self-described room version, + reject. +3. If the event fails [signature checks](https://spec.matrix.org/v1.15/server-server-api/#validating-hashes-and-signatures-on-received-events), + reject. The content hash check MAY be skipped as the event can safely be redacted prior to all of + these checks. +4. If the event's [reference hash](https://spec.matrix.org/v1.15/server-server-api/#calculating-the-reference-hash-for-an-event) + does not match the event ID contained in the room ID, reject. +5. Otherwise, allow. + + +### Client-Server API + +Using the same "affected" calculation above, when serving `m.room.create` in [Stripped State](https://spec.matrix.org/v1.15/client-server-api/#stripped-state) +to clients in affected room versions, servers MUST format that event in the same way it would for +[`GET /rooms/:roomId/event/:eventId`](https://spec.matrix.org/v1.15/client-server-api/#get_matrixclientv3roomsroomideventeventid). + +For unaffected room versions, servers SHOULD NOT format the create event, if known, any different than +what stripped state already requires. This is to ensure clients do not accidentally rely on information +which may be confusing to them, such as the "creator server name". This is especially true because the +server is required to treat those events as untrusted for the reasons described in MSC4291. + +**Note**: "serving to clients" includes [pushing to Application Services](https://spec.matrix.org/v1.15/application-service-api/#pushing-events). + + +## Potential issues + +* Not using the same format for both affected and unaffected room versions may lead to parser complexity. + This is considered tolerable by this proposal to ensure that clients (and servers) have limited + ability to confuse themselves. + +* This technique is not applied to other state events present in stripped state. A future MSC or + series of MSCs is expected to address this particular concern. + +* Some server implementations allow safety tooling and other applications to hook into them between + the Federation API and Client-Server API. Such implementations are encouraged to make the create + event reasonably available in its full form to those applications. Typically, this will be an internal + representation of the event which still has the capability to serialize down to a PDU. + + +## Alternatives + +This proposal fills a potential gap in information created by MSC4291, making the alternatives roughly +equivalent to "don't do this". + + +## Security considerations + +Security considerations are made throughout, especially in areas where a server may accidentally trust +data it shouldn't. + + +## Unstable prefix + +This proposal does not require an unstable prefix as the behaviour can be accomplished without overly +affecting client or server implementations. + + +## Dependencies + +This proposal requires [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291) in +order to make any amount of sense. From a982f53f2e22d06c0619ea1c6acf986f1bfa2956 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 11 Jul 2025 17:07:00 -0600 Subject: [PATCH 02/17] Clarify that we're not replacing auth checks on create events --- proposals/4311-stripped-state-create-event.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/4311-stripped-state-create-event.md b/proposals/4311-stripped-state-create-event.md index b7594edd2c6..fb8f7a5f79e 100644 --- a/proposals/4311-stripped-state-create-event.md +++ b/proposals/4311-stripped-state-create-event.md @@ -50,7 +50,8 @@ while one without a domain component (and happens to be `!<43 unpadded urlsafe b affected. This is done to ensure the server is not potentially confused by a malicious server providing a create event for a different, unaffected, room. -When a room is affected, the server MUST validate the `m.room.create` event as follows: +When a room is affected, the server MUST validate the `m.room.create` event as follows for the purposes +of the above: 1. If the event has a `room_id`, reject. 2. If the event does not otherwise comply with the event format for its self-described room version, From 78a138787f4b581aca7143302217c4e5d073e107 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 11 Jul 2025 17:09:57 -0600 Subject: [PATCH 03/17] Acknowledge disparity in unaffected room formats --- proposals/4311-stripped-state-create-event.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/proposals/4311-stripped-state-create-event.md b/proposals/4311-stripped-state-create-event.md index fb8f7a5f79e..bd4ad465cfa 100644 --- a/proposals/4311-stripped-state-create-event.md +++ b/proposals/4311-stripped-state-create-event.md @@ -92,6 +92,11 @@ server is required to treat those events as untrusted for the reasons described event reasonably available in its full form to those applications. Typically, this will be an internal representation of the event which still has the capability to serialize down to a PDU. +* For unaffected room versions, it's a little awkward that the Federation API SHOULD use PDU format, + but the Client-Server API SHOULD NOT format the event as a real event. This proposal makes this + choice to give *some* amount of information to intermediary toolling within the server, but can + easily be modified to be a "SHOULD NOT" for both cases. + ## Alternatives From 49719299961c4126e0d88490bb2c9fbeadfcd24e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 11 Jul 2025 17:12:53 -0600 Subject: [PATCH 04/17] This isn't a word despite what spellcheck thinks --- proposals/4311-stripped-state-create-event.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/4311-stripped-state-create-event.md b/proposals/4311-stripped-state-create-event.md index bd4ad465cfa..38e7b7565c3 100644 --- a/proposals/4311-stripped-state-create-event.md +++ b/proposals/4311-stripped-state-create-event.md @@ -94,7 +94,7 @@ server is required to treat those events as untrusted for the reasons described * For unaffected room versions, it's a little awkward that the Federation API SHOULD use PDU format, but the Client-Server API SHOULD NOT format the event as a real event. This proposal makes this - choice to give *some* amount of information to intermediary toolling within the server, but can + choice to give *some* amount of information to intermediary tooling within the server, but can easily be modified to be a "SHOULD NOT" for both cases. From 7d2c5f80cee8d689113939996668820f2f156345 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 24 Jul 2025 10:38:29 -0600 Subject: [PATCH 05/17] add migration steps --- proposals/4311-stripped-state-create-event.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/proposals/4311-stripped-state-create-event.md b/proposals/4311-stripped-state-create-event.md index 38e7b7565c3..a3df3f26657 100644 --- a/proposals/4311-stripped-state-create-event.md +++ b/proposals/4311-stripped-state-create-event.md @@ -116,6 +116,25 @@ This proposal does not require an unstable prefix as the behaviour can be accomp affecting client or server implementations. +## Migration + +*This section is non-normative for spec writing purposes. It only affects implementations which have +implemented room version 12 upon its release.* + +Room version 12 contains MSC4291 and is expected to be used in production prior to this proposal +becoming stable itself. To account for this, servers SHOULD treat "MUST" as "MAY" throughout this +proposal until 1 full spec release cycle has passed since this MSC's own release in the specification. + +This translates to a timeline anywhere between 2 and 6 months, depending on ecosystem rollout. An +example *possible* release schedule is: + +1. August 2025 - Matrix 1.16 is released with Room Version 12. +2. October 2025 - Matrix 1.17 is released with this proposal; servers use "MAY" keywords. +3. January 2026 - Matrix 1.18 is released; servers switch to "MUST" keywords. + +Servers MAY switch to "MUST" keywords early if their local ecosystems are prepared for the change. + + ## Dependencies This proposal requires [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291) in From eeb4640d4fb407a0ed17217b030b85c39d850fc2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 8 Aug 2025 11:46:51 -0600 Subject: [PATCH 06/17] Just use the normal stripped_state format --- proposals/4311-stripped-state-create-event.md | 27 ++++++------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/proposals/4311-stripped-state-create-event.md b/proposals/4311-stripped-state-create-event.md index a3df3f26657..4d9118448c2 100644 --- a/proposals/4311-stripped-state-create-event.md +++ b/proposals/4311-stripped-state-create-event.md @@ -66,24 +66,18 @@ of the above: ### Client-Server API -Using the same "affected" calculation above, when serving `m.room.create` in [Stripped State](https://spec.matrix.org/v1.15/client-server-api/#stripped-state) -to clients in affected room versions, servers MUST format that event in the same way it would for -[`GET /rooms/:roomId/event/:eventId`](https://spec.matrix.org/v1.15/client-server-api/#get_matrixclientv3roomsroomideventeventid). - -For unaffected room versions, servers SHOULD NOT format the create event, if known, any different than -what stripped state already requires. This is to ensure clients do not accidentally rely on information -which may be confusing to them, such as the "creator server name". This is especially true because the -server is required to treat those events as untrusted for the reasons described in MSC4291. - -**Note**: "serving to clients" includes [pushing to Application Services](https://spec.matrix.org/v1.15/application-service-api/#pushing-events). +A prior iteration of this proposal required that servers format the `m.room.create` event as a full +client event in affected rooms, however that format did not have a strong use case for deviating from +the regular [Stripped State](https://spec.matrix.org/v1.15/client-server-api/#stripped-state) format. +Instead, this proposal makes *no* changes to the format of `m.room.create` in stripped state over the +Client-Server API, meaning the `m.room.create` event is represented as a regular stripped state event. +For history on this change, see [this thread](https://github.com/matrix-org/matrix-spec-proposals/pull/4311/files#r2232855570). +**Note**: Servers can technically return more than specified in stripped state if they like, though +this is not usually recommended as clients may unintentionally rely on that behaviour. ## Potential issues -* Not using the same format for both affected and unaffected room versions may lead to parser complexity. - This is considered tolerable by this proposal to ensure that clients (and servers) have limited - ability to confuse themselves. - * This technique is not applied to other state events present in stripped state. A future MSC or series of MSCs is expected to address this particular concern. @@ -92,11 +86,6 @@ server is required to treat those events as untrusted for the reasons described event reasonably available in its full form to those applications. Typically, this will be an internal representation of the event which still has the capability to serialize down to a PDU. -* For unaffected room versions, it's a little awkward that the Federation API SHOULD use PDU format, - but the Client-Server API SHOULD NOT format the event as a real event. This proposal makes this - choice to give *some* amount of information to intermediary tooling within the server, but can - easily be modified to be a "SHOULD NOT" for both cases. - ## Alternatives From 05b8b49a3c1f616f64bbe01c82d3654850dedad8 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 8 Aug 2025 12:08:39 -0600 Subject: [PATCH 07/17] Rewrite problem statement and solution components to match new scope --- proposals/4311-stripped-state-create-event.md | 54 +++++++------------ 1 file changed, 20 insertions(+), 34 deletions(-) diff --git a/proposals/4311-stripped-state-create-event.md b/proposals/4311-stripped-state-create-event.md index 4d9118448c2..42b41b7bb4b 100644 --- a/proposals/4311-stripped-state-create-event.md +++ b/proposals/4311-stripped-state-create-event.md @@ -2,33 +2,30 @@ Historically, when processing an invite or knock, safety tooling would parse the room ID despite [being opaque](https://spec.matrix.org/v1.15/appendices/#room-ids) to determine the server which -originally created the room. If that server was considered abusive, the invite/knock may be rejected -or blocked early by the tooling. This approach is preferred because the user sending the invite may -not be on the same server as the user who created the room, but is often still checked by safety -tooling. +originally created the room. If that server was considered abusive, the incoming invite or outbound +knock may be rejected or blocked early by the tooling. This approach is preferred because the user +sending the invite may not be on the same server as the user who created the room, but is often still +checked by safety tooling. With [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291), room IDs lose their -domain component, which can make the first check described above harder if not impossible. When -speaking over federation however, [invites](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1inviteroomideventid) -and [knocks](https://spec.matrix.org/v1.15/server-server-api/#get_matrixfederationv1make_knockroomiduserid) -contain a concept of "stripped state events" which give (unsigned) context about the room for the -consuming clients. The Client-Server API [Stripped State](https://spec.matrix.org/v1.15/client-server-api/#stripped-state) -section has more information about what these 'events' are and how they work. +domain component. This, combined with [Stripped State](https://spec.matrix.org/v1.15/client-server-api/#stripped-state) +recommending rather than requiring the `m.room.create` event, makes the above check harder if not +impossible in some cases. -This MSC aims to reintroduce the accessibility of the creator's server name to clients (and safety -tooling) by requiring the `m.room.create` event *at least* be a full and proper PDU in affected room -versions when transiting the Federation API via stripped state, allowing intermediary servers and -clients to inspect the creator's domain name. +This MSC shifts the `m.room.create` event to a *required* stripped state event, and imposes validation +to ensure the event matches the room. To support the new validation, the `m.room.create` event must +be formatted as a full PDU in the stripped state of [invites](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1inviteroomideventid) +and [knocks](https://spec.matrix.org/v1.15/server-server-api/#get_matrixfederationv1make_knockroomiduserid) +over federation. Together, these changes allow safety tooling (and servers) to better validate invites +in particular. ## Proposal -This proposal is split into the Federation API changes and Client-Server API changes for clarity. - - -### Federation API +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), +where available. No other changes are proposed to the Client-Server API. -For room versions affected by [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291), +Over federation, for room versions affected by [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291), the `m.room.create` event MUST be included in [`invite_room_state`](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1inviteroomideventid) and [`knock_room_state`](https://spec.matrix.org/v1.15/server-server-api/#get_matrixfederationv1make_knockroomiduserid) and MUST be a properly-formatted PDU according to that room version's event format specification. @@ -64,18 +61,6 @@ of the above: 5. Otherwise, allow. -### Client-Server API - -A prior iteration of this proposal required that servers format the `m.room.create` event as a full -client event in affected rooms, however that format did not have a strong use case for deviating from -the regular [Stripped State](https://spec.matrix.org/v1.15/client-server-api/#stripped-state) format. -Instead, this proposal makes *no* changes to the format of `m.room.create` in stripped state over the -Client-Server API, meaning the `m.room.create` event is represented as a regular stripped state event. -For history on this change, see [this thread](https://github.com/matrix-org/matrix-spec-proposals/pull/4311/files#r2232855570). - -**Note**: Servers can technically return more than specified in stripped state if they like, though -this is not usually recommended as clients may unintentionally rely on that behaviour. - ## Potential issues * This technique is not applied to other state events present in stripped state. A future MSC or @@ -95,8 +80,8 @@ equivalent to "don't do this". ## Security considerations -Security considerations are made throughout, especially in areas where a server may accidentally trust -data it shouldn't. +Security considerations are made throughout, especially in areas where an implementation may accidentally +trust data it shouldn't. ## Unstable prefix @@ -112,7 +97,8 @@ implemented room version 12 upon its release.* Room version 12 contains MSC4291 and is expected to be used in production prior to this proposal becoming stable itself. To account for this, servers SHOULD treat "MUST" as "MAY" throughout this -proposal until 1 full spec release cycle has passed since this MSC's own release in the specification. +proposal, with the exception of the Client-Server API changes, until 1 full spec release cycle has +passed since this MSC's own release in the specification. This translates to a timeline anywhere between 2 and 6 months, depending on ecosystem rollout. An example *possible* release schedule is: From 5ac4656775f357fd5ceb4fb92e16aa19f0baaab9 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 12 Aug 2025 12:57:57 -0600 Subject: [PATCH 08/17] review: improve intro --- proposals/4311-stripped-state-create-event.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/proposals/4311-stripped-state-create-event.md b/proposals/4311-stripped-state-create-event.md index 42b41b7bb4b..72ff930c281 100644 --- a/proposals/4311-stripped-state-create-event.md +++ b/proposals/4311-stripped-state-create-event.md @@ -4,20 +4,24 @@ Historically, when processing an invite or knock, safety tooling would parse the [being opaque](https://spec.matrix.org/v1.15/appendices/#room-ids) to determine the server which originally created the room. If that server was considered abusive, the incoming invite or outbound knock may be rejected or blocked early by the tooling. This approach is preferred because the user -sending the invite may not be on the same server as the user who created the room, but is often still -checked by safety tooling. +sending the invite may not be on the same server as the user who created the room, though both sender +and creator are checked by safety tooling. With [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291), room IDs lose their domain component. This, combined with [Stripped State](https://spec.matrix.org/v1.15/client-server-api/#stripped-state) recommending rather than requiring the `m.room.create` event, makes the above check harder if not -impossible in some cases. +impossible when the create event is missing or incomplete, as the room ID cannot be confirmed in +MSC4291+ room versions. This MSC shifts the `m.room.create` event to a *required* stripped state event, and imposes validation to ensure the event matches the room. To support the new validation, the `m.room.create` event must be formatted as a full PDU in the stripped state of [invites](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1inviteroomideventid) -and [knocks](https://spec.matrix.org/v1.15/server-server-api/#get_matrixfederationv1make_knockroomiduserid) -over federation. Together, these changes allow safety tooling (and servers) to better validate invites -in particular. +over federation. This is not applied to other events for reasons described later in the proposal. + +[Knocks](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1send_knockroomideventid) +additionally include the full PDU format, though only to ensure symmetry between the two instances of +stripped state. It's not possible to prevent a knock based on stripped state because the server will +have already sent the knock before stripped state is received. ## Proposal From e651b619ddaeebccf366b82e456f0f55dacd4205 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 12 Aug 2025 13:03:40 -0600 Subject: [PATCH 09/17] review: clarify format --- proposals/4311-stripped-state-create-event.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/proposals/4311-stripped-state-create-event.md b/proposals/4311-stripped-state-create-event.md index 72ff930c281..20cc67eed0c 100644 --- a/proposals/4311-stripped-state-create-event.md +++ b/proposals/4311-stripped-state-create-event.md @@ -32,7 +32,9 @@ where available. No other changes are proposed to the Client-Server API. Over federation, for room versions affected by [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291), the `m.room.create` event MUST be included in [`invite_room_state`](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1inviteroomideventid) and [`knock_room_state`](https://spec.matrix.org/v1.15/server-server-api/#get_matrixfederationv1make_knockroomiduserid) -and MUST be a properly-formatted PDU according to that room version's event format specification. +and MUST be a properly-formatted PDU according to that room version's event format specification. The +full PDU format is used to ensure that receiving applications can independently verify the room ID +by calculating the reference hash of the create event themselves. If the `m.room.create` event is not present, not a PDU, or not for the room ID specified, the server MUST fail to continue processing the invite or knock. For invites, this is a `400 M_MISSING_PARAM` @@ -68,7 +70,11 @@ of the above: ## Potential issues * This technique is not applied to other state events present in stripped state. A future MSC or - series of MSCs is expected to address this particular concern. + series of MSCs is expected to address this particular concern. Specifically, future work is expected + to make it easier for applications to independently verify other events included in "stripped" state + when they become formatted as full PDUs too. (A rename from "stripped state" to something else may + also be required at that stage.) Until then, the other events are left in their stripped form to + indicate that they are explicitly untrusted data. * Some server implementations allow safety tooling and other applications to hook into them between the Federation API and Client-Server API. Such implementations are encouraged to make the create From afff25ed72eb7b71ee04cbdc22de86c5d4f21114 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 12 Aug 2025 13:10:53 -0600 Subject: [PATCH 10/17] review: fix knocks --- proposals/4311-stripped-state-create-event.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/proposals/4311-stripped-state-create-event.md b/proposals/4311-stripped-state-create-event.md index 20cc67eed0c..01d4800c5fc 100644 --- a/proposals/4311-stripped-state-create-event.md +++ b/proposals/4311-stripped-state-create-event.md @@ -31,17 +31,18 @@ where available. No other changes are proposed to the Client-Server API. Over federation, for room versions affected by [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291), the `m.room.create` event MUST be included in [`invite_room_state`](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1inviteroomideventid) -and [`knock_room_state`](https://spec.matrix.org/v1.15/server-server-api/#get_matrixfederationv1make_knockroomiduserid) +and [`knock_room_state`](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1send_knockroomideventid) and MUST be a properly-formatted PDU according to that room version's event format specification. The full PDU format is used to ensure that receiving applications can independently verify the room ID by calculating the reference hash of the create event themselves. If the `m.room.create` event is not present, not a PDU, or not for the room ID specified, the server -MUST fail to continue processing the invite or knock. For invites, this is a `400 M_MISSING_PARAM` -standard Matrix error (new to the endpoint). For knocks, this means the server drops the `make_knock` -response and never completes a `send_knock`. For both operations, the associated Client-Server API -request is failed with `500 M_BAD_STATE`. A 4xx error isn't used for the Client-Server API because -there's nothing the client can materially do differently to fix that request. +MUST respond to invites with a `400 M_MISSING_PARAM` standard Matrix error (new to the endpoint). For +knocks, the server SHOULD remove the `m.room.create` event from `knock_room_state` before passing the +information along to clients. Ideally, the server would be able to prevent the knock from happening, +though by the time the server can see the `knock_room_state`, the knock has already happened. A 4xx +error isn't used for the Client-Server API because there's nothing the client can materially do +differently to fix that request. For room versions *not* affected by MSC4291, servers SHOULD include the properly-formatted `m.room.create` PDU. This is not made mandatory to avoid a situation where servers trust data that shouldn't be trusted From 72f6a3a00b85b843dbf8cb20d71c9d36da938c2b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 12 Aug 2025 13:11:38 -0600 Subject: [PATCH 11/17] review: fix room_id calculation --- proposals/4311-stripped-state-create-event.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/4311-stripped-state-create-event.md b/proposals/4311-stripped-state-create-event.md index 01d4800c5fc..35347f0c0de 100644 --- a/proposals/4311-stripped-state-create-event.md +++ b/proposals/4311-stripped-state-create-event.md @@ -48,8 +48,9 @@ For room versions *not* affected by MSC4291, servers SHOULD include the properly PDU. This is not made mandatory to avoid a situation where servers trust data that shouldn't be trusted for the reasons described by MSC4291. -To determine whether a room is "affected" by MSC4291, servers MUST inspect the `room_id` rather than -the create event's `room_version`. Specifically, a room ID with a domain component is *not* affected +To determine whether a room is "affected" by MSC4291, servers MUST use the `room_id` rather than +the create event's `room_version` (note: for MSC4291 rooms, the server must calculate the room ID +because `room_id` will not be present on the event). Specifically, a room ID with a domain component is *not* affected while one without a domain component (and happens to be `!<43 unpadded urlsafe base64 chars>`) *is* affected. This is done to ensure the server is not potentially confused by a malicious server providing a create event for a different, unaffected, room. From bef65403ca2db18160334652a8ec81034737ebc0 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 12 Aug 2025 13:21:20 -0600 Subject: [PATCH 12/17] review: rework migration wording --- proposals/4311-stripped-state-create-event.md | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/proposals/4311-stripped-state-create-event.md b/proposals/4311-stripped-state-create-event.md index 35347f0c0de..f3debd052fe 100644 --- a/proposals/4311-stripped-state-create-event.md +++ b/proposals/4311-stripped-state-create-event.md @@ -104,22 +104,25 @@ affecting client or server implementations. ## Migration -*This section is non-normative for spec writing purposes. It only affects implementations which have -implemented room version 12 upon its release.* +*This section is for server implementations to follow upon release of room version 12. It is not +intended to enter the spec in any way.* Room version 12 contains MSC4291 and is expected to be used in production prior to this proposal -becoming stable itself. To account for this, servers SHOULD treat "MUST" as "MAY" throughout this -proposal, with the exception of the Client-Server API changes, until 1 full spec release cycle has -passed since this MSC's own release in the specification. +becoming stable itself. To account for this, for 1 spec release cycle, servers are encouraged to +warn rather than fail on invites which don't have a complete `m.room.create` PDU in the `invite_room_state`. +If the PDU is complete, but for a different room, the invite should still fail per the proposal text +above. This translates to a timeline anywhere between 2 and 6 months, depending on ecosystem rollout. An example *possible* release schedule is: -1. August 2025 - Matrix 1.16 is released with Room Version 12. -2. October 2025 - Matrix 1.17 is released with this proposal; servers use "MAY" keywords. -3. January 2026 - Matrix 1.18 is released; servers switch to "MUST" keywords. +1. August 2025 - Matrix 1.16 is released with Room Version 12 and this proposal; servers log warnings + about invites missing complete `m.room.create` PDUs. +2. October 2025 - Matrix 1.17 is released; servers stop using warnings and instead fully apply the + validation logic of this proposal, causing invites missing full create event PDUs to fail. -Servers MAY switch to "MUST" keywords early if their local ecosystems are prepared for the change. +Servers are encouraged to make the switch to full validation early if their ecosystem conditions +allow. For example, if logged warnings are sufficiently low or of insignicant consequence. ## Dependencies From 2104c97e1c1f5f7241c265ec9171bf762a0e67ec Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 14 Aug 2025 18:52:17 -0600 Subject: [PATCH 13/17] Fully format all events in stripped state --- proposals/4311-stripped-state-create-event.md | 85 ++++++++----------- 1 file changed, 34 insertions(+), 51 deletions(-) diff --git a/proposals/4311-stripped-state-create-event.md b/proposals/4311-stripped-state-create-event.md index f3debd052fe..b3bb1ee73b2 100644 --- a/proposals/4311-stripped-state-create-event.md +++ b/proposals/4311-stripped-state-create-event.md @@ -16,7 +16,7 @@ MSC4291+ room versions. This MSC shifts the `m.room.create` event to a *required* stripped state event, and imposes validation to ensure the event matches the room. To support the new validation, the `m.room.create` event must be formatted as a full PDU in the stripped state of [invites](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1inviteroomideventid) -over federation. This is not applied to other events for reasons described later in the proposal. +over federation. Similar treatment is applied to other stripped state events for uniformity. [Knocks](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1send_knockroomideventid) additionally include the full PDU format, though only to ensure symmetry between the two instances of @@ -27,73 +27,56 @@ have already sent the knock before stripped state is received. ## Proposal 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), -where available. No other changes are proposed to the Client-Server API. - -Over federation, for room versions affected by [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291), -the `m.room.create` event MUST be included in [`invite_room_state`](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1inviteroomideventid) -and [`knock_room_state`](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1send_knockroomideventid) -and MUST be a properly-formatted PDU according to that room version's event format specification. The -full PDU format is used to ensure that receiving applications can independently verify the room ID -by calculating the reference hash of the create event themselves. - -If the `m.room.create` event is not present, not a PDU, or not for the room ID specified, the server -MUST respond to invites with a `400 M_MISSING_PARAM` standard Matrix error (new to the endpoint). For -knocks, the server SHOULD remove the `m.room.create` event from `knock_room_state` before passing the -information along to clients. Ideally, the server would be able to prevent the knock from happening, -though by the time the server can see the `knock_room_state`, the knock has already happened. A 4xx -error isn't used for the Client-Server API because there's nothing the client can materially do -differently to fix that request. - -For room versions *not* affected by MSC4291, servers SHOULD include the properly-formatted `m.room.create` -PDU. This is not made mandatory to avoid a situation where servers trust data that shouldn't be trusted -for the reasons described by MSC4291. - -To determine whether a room is "affected" by MSC4291, servers MUST use the `room_id` rather than -the create event's `room_version` (note: for MSC4291 rooms, the server must calculate the room ID -because `room_id` will not be present on the event). Specifically, a room ID with a domain component is *not* affected -while one without a domain component (and happens to be `!<43 unpadded urlsafe base64 chars>`) *is* -affected. This is done to ensure the server is not potentially confused by a malicious server providing -a create event for a different, unaffected, room. - -When a room is affected, the server MUST validate the `m.room.create` event as follows for the purposes -of the above: - -1. If the event has a `room_id`, reject. -2. If the event does not otherwise comply with the event format for its self-described room version, - reject. -3. If the event fails [signature checks](https://spec.matrix.org/v1.15/server-server-api/#validating-hashes-and-signatures-on-received-events), - reject. The content hash check MAY be skipped as the event can safely be redacted prior to all of - these checks. -4. If the event's [reference hash](https://spec.matrix.org/v1.15/server-server-api/#calculating-the-reference-hash-for-an-event) - does not match the event ID contained in the room ID, reject. -5. Otherwise, allow. +where available. No other changes are proposed to the Client-Server API. For clarity, this means clients +continue to receive events which only have `content`, `sender`, `state_key` (optional), and `type` in +the `invite_room_state`, `knock_room_state`, and whereever else stripped state is used. +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) +and [`knock_room_state`](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1send_knockroomideventid). +Servers MUST additionally format events in `invite_room_state` and `knock_room_state` as PDUs according +to that room version's event format specification. Together, these changes allow servers to validate +the room ID matches the invite (or knock, though it's already sent by the time validation would happen). -## Potential issues +Specifically, including the `m.room.create` event as a full PDU allows servers to calculate the room +ID by hashing the event in MSC4291+ room versions. For other room versions (1 through 11), the server +can at most compare the `room_id` field of the create event with the invite/knock membership event. + +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), +or the `m.room.create` event is missing, the receiving server MUST respond to invites with a `400 M_MISSING_PARAM` +standard Matrix error (new to the endpoint). For knocks, the server SHOULD remove any events from +`knock_room_state` which fail the same validation check before passing the details along to clients. +Ideally, the server would be able to prevent the knock from happening, though by the time the server +can see the `knock_room_state`, the knock has already happened. + +The `400 M_MISSING_PARAM` error SHOULD be translated to a 5xx error by the sending server over the +Client-Server API. This is done because there's nothing the client can materially do differently to +make the request succeed. -* This technique is not applied to other state events present in stripped state. A future MSC or - series of MSCs is expected to address this particular concern. Specifically, future work is expected - to make it easier for applications to independently verify other events included in "stripped" state - when they become formatted as full PDUs too. (A rename from "stripped state" to something else may - also be required at that stage.) Until then, the other events are left in their stripped form to - indicate that they are explicitly untrusted data. +When comparing the room IDs, servers will need to calculate the room ID from the `m.room.create` event +as described by MSC4291 (take the reference hash of the event for an event ID, swap the sigil). + + +## Potential issues * Some server implementations allow safety tooling and other applications to hook into them between the Federation API and Client-Server API. Such implementations are encouraged to make the create event reasonably available in its full form to those applications. Typically, this will be an internal representation of the event which still has the capability to serialize down to a PDU. +* Implementations should take care to not unintentionally trust the events contained in `invite_room_state` + and `knock_room_state`, despite appearing as complete events. This is due to the lack of each event's + auth chain being included, and reassurance that the events are the current events. ## Alternatives This proposal fills a potential gap in information created by MSC4291, making the alternatives roughly -equivalent to "don't do this". +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) +where the `/invite` endpoint changes, however the changes are roughly the same as this proposal's. ## Security considerations -Security considerations are made throughout, especially in areas where an implementation may accidentally -trust data it shouldn't. +Security considerations are made throughout, especially around validating the events included. ## Unstable prefix From 05b3d96eca020375ede2dc28cb15c89d83f44731 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 19 Aug 2025 08:48:46 -0600 Subject: [PATCH 14/17] Spelling --- proposals/4311-stripped-state-create-event.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/4311-stripped-state-create-event.md b/proposals/4311-stripped-state-create-event.md index b3bb1ee73b2..d126a94e454 100644 --- a/proposals/4311-stripped-state-create-event.md +++ b/proposals/4311-stripped-state-create-event.md @@ -29,7 +29,7 @@ have already sent the knock before stripped state is received. 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), where available. No other changes are proposed to the Client-Server API. For clarity, this means clients continue to receive events which only have `content`, `sender`, `state_key` (optional), and `type` in -the `invite_room_state`, `knock_room_state`, and whereever else stripped state is used. +the `invite_room_state`, `knock_room_state`, and wherever else stripped state is used. 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) and [`knock_room_state`](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1send_knockroomideventid). From 249dec303c14e3bb1ddc4046d2c2a5d409f2603d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 19 Aug 2025 09:02:35 -0600 Subject: [PATCH 15/17] Make migration normative --- proposals/4311-stripped-state-create-event.md | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/proposals/4311-stripped-state-create-event.md b/proposals/4311-stripped-state-create-event.md index d126a94e454..8a8d41c00f5 100644 --- a/proposals/4311-stripped-state-create-event.md +++ b/proposals/4311-stripped-state-create-event.md @@ -48,6 +48,9 @@ standard Matrix error (new to the endpoint). For knocks, the server SHOULD remov Ideally, the server would be able to prevent the knock from happening, though by the time the server can see the `knock_room_state`, the knock has already happened. +**Note**: Servers SHOULD consider their local ecosystems before imposing this validation completely, +per the "Migration" section later in this document. + The `400 M_MISSING_PARAM` error SHOULD be translated to a 5xx error by the sending server over the Client-Server API. This is done because there's nothing the client can materially do differently to make the request succeed. @@ -87,25 +90,13 @@ affecting client or server implementations. ## Migration -*This section is for server implementations to follow upon release of room version 12. It is not -intended to enter the spec in any way.* - -Room version 12 contains MSC4291 and is expected to be used in production prior to this proposal -becoming stable itself. To account for this, for 1 spec release cycle, servers are encouraged to -warn rather than fail on invites which don't have a complete `m.room.create` PDU in the `invite_room_state`. -If the PDU is complete, but for a different room, the invite should still fail per the proposal text -above. - -This translates to a timeline anywhere between 2 and 6 months, depending on ecosystem rollout. An -example *possible* release schedule is: - -1. August 2025 - Matrix 1.16 is released with Room Version 12 and this proposal; servers log warnings - about invites missing complete `m.room.create` PDUs. -2. October 2025 - Matrix 1.17 is released; servers stop using warnings and instead fully apply the - validation logic of this proposal, causing invites missing full create event PDUs to fail. +Mentioned above, existing server implementations SHOULD warn rather than fail on invites which don't +have complete PDUs inside `invite_room_state` until their local ecosystem adoption allows for the +full set of validation to be applied. If PDUs are complete, but for a different room, the invite MUST +still fail per the validation above. -Servers are encouraged to make the switch to full validation early if their ecosystem conditions -allow. For example, if logged warnings are sufficiently low or of insignicant consequence. +This proposal suggests that servers wait no longer than 3 months (or about 1 full spec release cycle) +after this proposal is released to enforce the full validation. ## Dependencies From d34f7963fb5ca2bb372ce0e28df726b807f3322f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 5 Sep 2025 11:47:16 -0600 Subject: [PATCH 16/17] Apply suggestions from code review Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- proposals/4311-stripped-state-create-event.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/proposals/4311-stripped-state-create-event.md b/proposals/4311-stripped-state-create-event.md index 8a8d41c00f5..05c0aa6f821 100644 --- a/proposals/4311-stripped-state-create-event.md +++ b/proposals/4311-stripped-state-create-event.md @@ -1,11 +1,11 @@ -# MSC4311: Ensuring the create event is available on invites and knocks +# MSC4311: Ensuring the create event is available on invites -Historically, when processing an invite or knock, safety tooling would parse the room ID despite -[being opaque](https://spec.matrix.org/v1.15/appendices/#room-ids) to determine the server which -originally created the room. If that server was considered abusive, the incoming invite or outbound -knock may be rejected or blocked early by the tooling. This approach is preferred because the user -sending the invite may not be on the same server as the user who created the room, though both sender -and creator are checked by safety tooling. +Historically, when processing an incoming invite or outgoing knock, safety tooling would parse the room ID despite +[being opaque](https://spec.matrix.org/v1.15/appendices/#room-ids), to determine the server which +originally created the room. If that server was considered abusive, the invite or +knock may be rejected or blocked early by the tooling. Note that checking the domain of the +sender of an invite is inadequate, because the sender may not be on the same server as the +user who created the room. With [MSC4291](https://github.com/matrix-org/matrix-spec-proposals/pull/4291), room IDs lose their domain component. This, combined with [Stripped State](https://spec.matrix.org/v1.15/client-server-api/#stripped-state) @@ -13,7 +13,8 @@ recommending rather than requiring the `m.room.create` event, makes the above ch impossible when the create event is missing or incomplete, as the room ID cannot be confirmed in MSC4291+ room versions. -This MSC shifts the `m.room.create` event to a *required* stripped state event, and imposes validation +To mitigate the problem in the case of invites, +this MSC shifts the `m.room.create` event to a *required* stripped state event, and imposes validation to ensure the event matches the room. To support the new validation, the `m.room.create` event must be formatted as a full PDU in the stripped state of [invites](https://spec.matrix.org/v1.15/server-server-api/#put_matrixfederationv1inviteroomideventid) over federation. Similar treatment is applied to other stripped state events for uniformity. From b8ec2f6bb99caa6ed794b51d212c13b4291e0afc Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 5 Sep 2025 11:54:43 -0600 Subject: [PATCH 17/17] Adjust requirements on servers --- proposals/4311-stripped-state-create-event.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/proposals/4311-stripped-state-create-event.md b/proposals/4311-stripped-state-create-event.md index 05c0aa6f821..2c861a13f2e 100644 --- a/proposals/4311-stripped-state-create-event.md +++ b/proposals/4311-stripped-state-create-event.md @@ -2,7 +2,7 @@ Historically, when processing an incoming invite or outgoing knock, safety tooling would parse the room ID despite [being opaque](https://spec.matrix.org/v1.15/appendices/#room-ids), to determine the server which -originally created the room. If that server was considered abusive, the invite or +originally created the room. If that server was considered abusive, the invite or knock may be rejected or blocked early by the tooling. Note that checking the domain of the sender of an invite is inadequate, because the sender may not be on the same server as the user who created the room. @@ -43,8 +43,9 @@ ID by hashing the event in MSC4291+ room versions. For other room versions (1 th can at most compare the `room_id` field of the create event with the invite/knock membership event. 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), -or the `m.room.create` event is missing, the receiving server MUST respond to invites with a `400 M_MISSING_PARAM` -standard Matrix error (new to the endpoint). For knocks, the server SHOULD remove any events from +or the `m.room.create` event is missing, the receiving server MAY respond to invites with a `400 M_MISSING_PARAM` +standard Matrix error (new to the endpoint). For invites to room version 12+ rooms, servers SHOULD +rather than MAY respond to such requests with `400 M_MISSING_PARAM`. For knocks, the server SHOULD remove any events from `knock_room_state` which fail the same validation check before passing the details along to clients. Ideally, the server would be able to prevent the knock from happening, though by the time the server can see the `knock_room_state`, the knock has already happened. @@ -93,11 +94,12 @@ affecting client or server implementations. Mentioned above, existing server implementations SHOULD warn rather than fail on invites which don't have complete PDUs inside `invite_room_state` until their local ecosystem adoption allows for the -full set of validation to be applied. If PDUs are complete, but for a different room, the invite MUST -still fail per the validation above. +full set of validation to be applied. If PDUs are complete, but for a different room, the invite SHOULD +still fail in v12 rooms per the validation above. This proposal suggests that servers wait no longer than 3 months (or about 1 full spec release cycle) -after this proposal is released to enforce the full validation. +after this proposal is released to enforce the full validation, though servers may extend this as +needed for their ecosystems to gain support. ## Dependencies