From 624d7cb37cd5182aec6168ca09a07d866e6720de Mon Sep 17 00:00:00 2001 From: gnuxie Date: Tue, 9 Apr 2024 15:05:53 +0100 Subject: [PATCH 01/18] server auth simple. --- proposals/0000-server-auth-simple.md | 130 +++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 proposals/0000-server-auth-simple.md diff --git a/proposals/0000-server-auth-simple.md b/proposals/0000-server-auth-simple.md new file mode 100644 index 00000000000..be30eee3d8e --- /dev/null +++ b/proposals/0000-server-auth-simple.md @@ -0,0 +1,130 @@ +# MSC0000: Simple server authorization + +This MSC proposes simple authorization rules that consider the origin +server of a given event, with the aim of replacing `m.room.server_acl`. + +This is a compromising MSC based on [MSC4099](https://github.com/matrix-org/matrix-spec-proposals/pull/4099) +that tries to use concepts even more inline current authorization events, +and without changing the `/make_join` handshake. +This MSC was also created in reaction to [MSC2870](https://github.com/matrix-org/matrix-spec-proposals/pull/2870), +that describes itself as stop gap to cover what the MSC has described +short comings of `m.room.server_acl`. We also agree that MSC2870 is +a stop gap and that the `m.room.server_acl` has severe shortcomings, +but we take the view that after 4 years of proposed stop-gapping, +there is enough time to introduce a more complete solution. + +## Proposal + +### The subscription authorization rule + +This rule is be inserted after rule 3 in version 11, the check +for `m.room.create`'s content field `m.federate`. + +1. If the type is `m.server.subscription`: + 1. If the `state_key` does not contain the server name for the + origin server, reject. + 2. If the origin servers's current participation is `permitted`, allow. + 2. If the `m.server.subscription_rule` is `deny`, reject. + 3. If the origin server's current participation is `deny`, reject. + 4. Otherwise allow. + +The purpose of this rule is to allow a server to send a subscription +event, even if the `sender` has no membership event. + +### The participation authroziation rule + +This rule is to be inserted before rule 4 in version 11, +the check for `m.room.member`, and after the subscription rule +described in this proposal. + +1. If the origin server's current `participation` state is not `permitted`: + 1. If the `participation` state is `deny`, reject. + 2. If the `m.server.subscription_rule` is `deny`, reject. + 3. If the `m.server.subscription_rule` is anything other than `passive`, reject. + +### The `m.server.participation` authorization event, `state_key: ${origin_server_name}` + +This is an authorization event that is used to authrorize events +originating from the server named in the `state_key`. + +`participation` can be one of `permitted` or `deny`. +`participation` is protected from redaction. + +A denied server must not be sent a `m.server.participation` event unless +the targeted server is already present within the room, or it has +an existing `m.server.subscription` event. +This is to prevent malicious servers being made aware of rooms that +they have not yet discovered. + +A `reason` field can be present alongside `participation` in order to +explain the reason why a server has been `denied`. +This reason is to be shown to a joining, or previously present +server, so that the server's users can understand why they are not +being allowed to participate. + +### The `m.server.subscription_rule` event, `state_key: ''` + +This event has one field, `rule` which can be one of the following: + +- `deny`: Users are unable to send the `m.server.subscription` event + unless there is an existing `m.server.participation` event for the + server. +- `passive`: Users can send the `m.server.subscription` event without + corresponding membership or server participation. + +`rule` is protected from redaction. + +### The `m.server.subscription` event, `state_key: ${origin_server_name}` + +This event has one field, `reason` which is optional. This field +is redactable. The intent is for the reason field to be redactable +by room admins. + +Servers MUST check the `membership` of the `sender` before sending +to confirm that the `membership` of the sender is not `ban`. +This is to prevent users changing the reason to be malicious without +being joined to the room, without forcing room admins to `deny` the +entire server from participating. Room admins should `deny` +the server if they continue to modify the reason maliciously or +fail to perform the aforementioned check. This will prevent the server +from sending furhter `m.server.subscription` events. + +## Potential issues + +### Racing with `m.server.subcription_rule`? + +We will embed `m.server.subscription_rule` in `m.room.create` if it +someone raises concerns about a potential race condition or other issue +about this conflicting with `m.server.participation`. However, stating +that there might be without elaboration is not helpful, I'd need to +know how the race works. If there is insistence, then we will embed +within the `m.room.create` event. + +### `subscription` might not be an ideal term + +`subscription` might not be an ideal term. + +### Soft failure of backfilled messages + +Servers that had `participation` of `permitted` that are later +denied via `deny`, will have their historical messages soft failed by +servers which later join. + +This should be addressed with [MSC4104](https://github.com/matrix-org/matrix-spec-proposals/pull/4104). + +## Alternatives + +- [MSC4099](https://github.com/matrix-org/matrix-spec-proposals/pull/4099) Participation based authorization for servers in the Matrix DAG +- [MSC3953](https://github.com/matrix-org/matrix-spec-proposals/pull/3953) Server capability DAG + +## Security considerations + +None considered. + +## Unstable prefix + +`me.marewolf.msc0000.*` + +## Dependencies + +No dependencies From 8b57646e49e47db71fd3149a36bab0480fc801ba Mon Sep 17 00:00:00 2001 From: gnuxie Date: Tue, 9 Apr 2024 15:08:33 +0100 Subject: [PATCH 02/18] Add related issues. --- proposals/0000-server-auth-simple.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/0000-server-auth-simple.md b/proposals/0000-server-auth-simple.md index be30eee3d8e..182cc39a507 100644 --- a/proposals/0000-server-auth-simple.md +++ b/proposals/0000-server-auth-simple.md @@ -13,6 +13,9 @@ a stop gap and that the `m.room.server_acl` has severe shortcomings, but we take the view that after 4 years of proposed stop-gapping, there is enough time to introduce a more complete solution. +Related issues: +- https://github.com/matrix-org/matrix-spec/issues/928 + ## Proposal ### The subscription authorization rule From d1085590d2930b161e95771f1d3aafc6373e1d1c Mon Sep 17 00:00:00 2001 From: gnuxie Date: Tue, 9 Apr 2024 15:11:15 +0100 Subject: [PATCH 03/18] spell check. --- proposals/0000-server-auth-simple.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/0000-server-auth-simple.md b/proposals/0000-server-auth-simple.md index 182cc39a507..bb3a9c23bc2 100644 --- a/proposals/0000-server-auth-simple.md +++ b/proposals/0000-server-auth-simple.md @@ -10,7 +10,7 @@ This MSC was also created in reaction to [MSC2870](https://github.com/matrix-org that describes itself as stop gap to cover what the MSC has described short comings of `m.room.server_acl`. We also agree that MSC2870 is a stop gap and that the `m.room.server_acl` has severe shortcomings, -but we take the view that after 4 years of proposed stop-gapping, +but we take the view that after 4 years of proposed stop-gaping, there is enough time to introduce a more complete solution. Related issues: @@ -26,7 +26,7 @@ for `m.room.create`'s content field `m.federate`. 1. If the type is `m.server.subscription`: 1. If the `state_key` does not contain the server name for the origin server, reject. - 2. If the origin servers's current participation is `permitted`, allow. + 2. If the origin server's current participation is `permitted`, allow. 2. If the `m.server.subscription_rule` is `deny`, reject. 3. If the origin server's current participation is `deny`, reject. 4. Otherwise allow. @@ -34,7 +34,7 @@ for `m.room.create`'s content field `m.federate`. The purpose of this rule is to allow a server to send a subscription event, even if the `sender` has no membership event. -### The participation authroziation rule +### The participation authorization rule This rule is to be inserted before rule 4 in version 11, the check for `m.room.member`, and after the subscription rule @@ -47,7 +47,7 @@ described in this proposal. ### The `m.server.participation` authorization event, `state_key: ${origin_server_name}` -This is an authorization event that is used to authrorize events +This is an authorization event that is used to authorize events originating from the server named in the `state_key`. `participation` can be one of `permitted` or `deny`. @@ -90,7 +90,7 @@ being joined to the room, without forcing room admins to `deny` the entire server from participating. Room admins should `deny` the server if they continue to modify the reason maliciously or fail to perform the aforementioned check. This will prevent the server -from sending furhter `m.server.subscription` events. +from sending further `m.server.subscription` events. ## Potential issues From 9ee526c81afd117008822a35793e4326690c7cb8 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Tue, 9 Apr 2024 15:20:50 +0100 Subject: [PATCH 04/18] notes on the `active` rule. --- proposals/0000-server-auth-simple.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/proposals/0000-server-auth-simple.md b/proposals/0000-server-auth-simple.md index bb3a9c23bc2..8f976222726 100644 --- a/proposals/0000-server-auth-simple.md +++ b/proposals/0000-server-auth-simple.md @@ -74,9 +74,25 @@ This event has one field, `rule` which can be one of the following: server. - `passive`: Users can send the `m.server.subscription` event without corresponding membership or server participation. +- `active`: Users can send the `m.server.subscription` event but + cannot send any other event without a corresponding + participation of `permitted`. `rule` is protected from redaction. +The `passive` state allows for rooms to operate as they do today, +new servers can freely join a room and start sending events without +prior approval from the administrators + +The `active` state allows for a much safer way to run public Matrix rooms, +new servers can join a room, send the `m.srever.subscription` event +but cannot do more until a room administrator permits the new joiner with +an `m.server.participation` event. We expect that in practice automated +tooling will perform a simple reputation check and immediately permit +a new server to participate. This is an essential part of the proposal +as the `active` mechanism eliminates a current shortfall that +`m.room.server_acl` is a purely reactive tool in a join wave attack. + ### The `m.server.subscription` event, `state_key: ${origin_server_name}` This event has one field, `reason` which is optional. This field From 88876e7a89d2b77745aa1d69e74a978320674e5b Mon Sep 17 00:00:00 2001 From: gnuxie Date: Tue, 9 Apr 2024 15:24:59 +0100 Subject: [PATCH 05/18] 4124 --- .../{0000-server-auth-simple.md => 4124-server-auth-simple.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename proposals/{0000-server-auth-simple.md => 4124-server-auth-simple.md} (100%) diff --git a/proposals/0000-server-auth-simple.md b/proposals/4124-server-auth-simple.md similarity index 100% rename from proposals/0000-server-auth-simple.md rename to proposals/4124-server-auth-simple.md From 5d4adb8f6d011580eea04c334e263906af42471f Mon Sep 17 00:00:00 2001 From: gnuxie Date: Tue, 9 Apr 2024 15:26:00 +0100 Subject: [PATCH 06/18] 4124 title --- proposals/4124-server-auth-simple.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/4124-server-auth-simple.md b/proposals/4124-server-auth-simple.md index 8f976222726..a0d9ed919cb 100644 --- a/proposals/4124-server-auth-simple.md +++ b/proposals/4124-server-auth-simple.md @@ -1,4 +1,4 @@ -# MSC0000: Simple server authorization +# MSC4124: Simple server authorization This MSC proposes simple authorization rules that consider the origin server of a given event, with the aim of replacing `m.room.server_acl`. From 05a6ed0170032138007e6b91cce817490d917d2c Mon Sep 17 00:00:00 2001 From: gnuxie Date: Tue, 9 Apr 2024 15:30:12 +0100 Subject: [PATCH 07/18] 4124 prefix https://github.com/matrix-org/matrix-spec/issues/928 --- proposals/4124-server-auth-simple.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/4124-server-auth-simple.md b/proposals/4124-server-auth-simple.md index a0d9ed919cb..c290810d3ed 100644 --- a/proposals/4124-server-auth-simple.md +++ b/proposals/4124-server-auth-simple.md @@ -142,7 +142,7 @@ None considered. ## Unstable prefix -`me.marewolf.msc0000.*` +`me.marewolf.msc4124.*` ## Dependencies From 27fc414bdec4888a8a6cdce05493c34317e1e9bd Mon Sep 17 00:00:00 2001 From: gnuxie Date: Tue, 9 Apr 2024 20:20:45 +0100 Subject: [PATCH 08/18] Rename subscription -> knock We now only allow one knock ever per server and these should only refrence the `m.room.create` event. https://github.com/matrix-org/matrix-spec-proposals/pull/4124#discussion_r1558042612 --- proposals/4124-server-auth-simple.md | 82 +++++++++++++++------------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/proposals/4124-server-auth-simple.md b/proposals/4124-server-auth-simple.md index c290810d3ed..d42d6f9925c 100644 --- a/proposals/4124-server-auth-simple.md +++ b/proposals/4124-server-auth-simple.md @@ -4,8 +4,7 @@ This MSC proposes simple authorization rules that consider the origin server of a given event, with the aim of replacing `m.room.server_acl`. This is a compromising MSC based on [MSC4099](https://github.com/matrix-org/matrix-spec-proposals/pull/4099) -that tries to use concepts even more inline current authorization events, -and without changing the `/make_join` handshake. +that tries to use concepts even more inline current authorization events This MSC was also created in reaction to [MSC2870](https://github.com/matrix-org/matrix-spec-proposals/pull/2870), that describes itself as stop gap to cover what the MSC has described short comings of `m.room.server_acl`. We also agree that MSC2870 is @@ -18,32 +17,43 @@ Related issues: ## Proposal -### The subscription authorization rule +### The `m.server.knock` authorization rule This rule is be inserted after rule 3 in version 11, the check for `m.room.create`'s content field `m.federate`. -1. If the type is `m.server.subscription`: +1. If the type is `m.server.knock`: 1. If the `state_key` does not contain the server name for the origin server, reject. - 2. If the origin server's current participation is `permitted`, allow. - 2. If the `m.server.subscription_rule` is `deny`, reject. - 3. If the origin server's current participation is `deny`, reject. - 4. Otherwise allow. + 2. If there is existing state for the origin server's `m.server.knock`, reject. + 3. If the origin server's current participation is `permitted`, allow. + 4. If the `m.server.knock_rule` is `deny`, reject. + 5. If the origin server's current participation is `deny`, reject. + 6. Otherwise allow. -The purpose of this rule is to allow a server to send a subscription +The purpose of this rule is to allow a server to send a knock event, even if the `sender` has no membership event. -### The participation authorization rule +The purpose of rule 1.2 is to prevent denied servers from ever being +given the ability to craft any event whatsoever in a room that has always +had the `active` `m.server.knock_rule`. +This is because an `m.server.participation` event set to `deny` will +usually be topologically older than an `m.server.knock` due to the +`m.server.participation` usually referencing a recent +`m.room.power_levels` event. And so `m.server.knock` events could +be crafted by malicious servers without restriction without +rule 1.2. + +### The `m.server.participation` authorization rule This rule is to be inserted before rule 4 in version 11, -the check for `m.room.member`, and after the subscription rule +the check for `m.room.member`, and after the `m.server.knock` rule described in this proposal. 1. If the origin server's current `participation` state is not `permitted`: 1. If the `participation` state is `deny`, reject. - 2. If the `m.server.subscription_rule` is `deny`, reject. - 3. If the `m.server.subscription_rule` is anything other than `passive`, reject. + 2. If the `m.server.knock_rule` is `deny`, reject. + 3. If the `m.server.knock_rule` is anything other than `passive`, reject. ### The `m.server.participation` authorization event, `state_key: ${origin_server_name}` @@ -55,7 +65,7 @@ originating from the server named in the `state_key`. A denied server must not be sent a `m.server.participation` event unless the targeted server is already present within the room, or it has -an existing `m.server.subscription` event. +an existing `m.server.knock` event. This is to prevent malicious servers being made aware of rooms that they have not yet discovered. @@ -65,16 +75,16 @@ This reason is to be shown to a joining, or previously present server, so that the server's users can understand why they are not being allowed to participate. -### The `m.server.subscription_rule` event, `state_key: ''` +### The `m.server.knock_rule` event, `state_key: ''` This event has one field, `rule` which can be one of the following: -- `deny`: Users are unable to send the `m.server.subscription` event +- `deny`: Users are unable to send the `m.server.knock` event unless there is an existing `m.server.participation` event for the server. -- `passive`: Users can send the `m.server.subscription` event without +- `passive`: Users can send the `m.server.knock` event without corresponding membership or server participation. -- `active`: Users can send the `m.server.subscription` event but +- `active`: Users can send the `m.server.knock` event but cannot send any other event without a corresponding participation of `permitted`. @@ -85,7 +95,7 @@ new servers can freely join a room and start sending events without prior approval from the administrators The `active` state allows for a much safer way to run public Matrix rooms, -new servers can join a room, send the `m.srever.subscription` event +new servers can join a room, send the `m.server.knock` event but cannot do more until a room administrator permits the new joiner with an `m.server.participation` event. We expect that in practice automated tooling will perform a simple reputation check and immediately permit @@ -93,36 +103,34 @@ a new server to participate. This is an essential part of the proposal as the `active` mechanism eliminates a current shortfall that `m.room.server_acl` is a purely reactive tool in a join wave attack. -### The `m.server.subscription` event, `state_key: ${origin_server_name}` +### The `m.server.knock` event, `state_key: ${origin_server_name}` + +This event has no fields, because it can only be sent once, and +therefore cannot be edited if the wrong or malicious information +is provided. + +The intent of the event is to only let the room administrators +explicitly aware of the server's existence. -This event has one field, `reason` which is optional. This field -is redactable. The intent is for the reason field to be redactable -by room admins. +### The `make_server_knock` handshake 💀 -Servers MUST check the `membership` of the `sender` before sending -to confirm that the `membership` of the sender is not `ban`. -This is to prevent users changing the reason to be malicious without -being joined to the room, without forcing room admins to `deny` the -entire server from participating. Room admins should `deny` -the server if they continue to modify the reason maliciously or -fail to perform the aforementioned check. This will prevent the server -from sending further `m.server.subscription` events. +TBC. + +This is needed because otherwise any server can send the +`m.server.knock` event for any other server, including random garbage +for server names and users that do not exist. ## Potential issues -### Racing with `m.server.subcription_rule`? +### Racing with `m.server.knock_rule`? -We will embed `m.server.subscription_rule` in `m.room.create` if it +We will embed `m.server.knock_rule` in `m.room.create` if it someone raises concerns about a potential race condition or other issue about this conflicting with `m.server.participation`. However, stating that there might be without elaboration is not helpful, I'd need to know how the race works. If there is insistence, then we will embed within the `m.room.create` event. -### `subscription` might not be an ideal term - -`subscription` might not be an ideal term. - ### Soft failure of backfilled messages Servers that had `participation` of `permitted` that are later From 9dc0fa2797251319719916578a7d34368b0a5762 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Tue, 9 Apr 2024 20:36:00 +0100 Subject: [PATCH 09/18] make_server_knock handshake. --- proposals/4124-server-auth-simple.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/proposals/4124-server-auth-simple.md b/proposals/4124-server-auth-simple.md index d42d6f9925c..9cabdc561d3 100644 --- a/proposals/4124-server-auth-simple.md +++ b/proposals/4124-server-auth-simple.md @@ -112,13 +112,19 @@ is provided. The intent of the event is to only let the room administrators explicitly aware of the server's existence. -### The `make_server_knock` handshake 💀 +### The `make_server_knock` handshake -TBC. +This MSC requires a very simple clone of the `make_knock` handshake +for the purpose of signing and creating the `m.server.knock` event. -This is needed because otherwise any server can send the -`m.server.knock` event for any other server, including random garbage -for server names and users that do not exist. +The details of this handshake are left outside the scope of the MSC, +as it may be decided that an API providing an agnostic unification of +`make_knock` and `make_join` should be used instead that signs +both the membership event and the `m.server.knock` event templates. + +We believe that the open choice here should not alone be a reason +to block this MSC from consideration. But we will follow up +with a clone of the `make_knock` handshake if requested. ## Potential issues @@ -154,4 +160,5 @@ None considered. ## Dependencies -No dependencies +No direct dependencies +See `make_server_knock` handshake. From eef34e0e1a3ea2d2ad13b2ea89cc73335006e923 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Tue, 9 Apr 2024 22:30:40 +0100 Subject: [PATCH 10/18] issues update --- proposals/4124-server-auth-simple.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/proposals/4124-server-auth-simple.md b/proposals/4124-server-auth-simple.md index 9cabdc561d3..c9fb8a24ffc 100644 --- a/proposals/4124-server-auth-simple.md +++ b/proposals/4124-server-auth-simple.md @@ -137,13 +137,22 @@ that there might be without elaboration is not helpful, I'd need to know how the race works. If there is insistence, then we will embed within the `m.room.create` event. -### Soft failure of backfilled messages +### Soft failure of messages Servers that had `participation` of `permitted` that are later -denied via `deny`, will have their historical messages soft failed by -servers which later join. +denied via `deny`, can have some of their messages soft failed +while the forks synchronise similar to https://github.com/matrix-org/synapse/issues/9329. -This should be addressed with [MSC4104](https://github.com/matrix-org/matrix-spec-proposals/pull/4104). +This could be addressed with [MSC4104](https://github.com/matrix-org/matrix-spec-proposals/pull/4104). + +### Mismatch with `m.room.power_levels` + +There is an argument to be made that the ability to manage +`m.server.participation` should not be flat in the way that +`m.room.server_acl` is. Consider Alice being the room creator +and Bob being an admin. Bob could create an `m.server.participation` +event that denies Alice's server from participating, even if Alice +is the same or a higher power level. ## Alternatives From 8df29268babafda90d9aa77011740392e56cdf0c Mon Sep 17 00:00:00 2001 From: gnuxie Date: Wed, 10 Apr 2024 13:31:16 +0100 Subject: [PATCH 11/18] spec links --- proposals/4124-server-auth-simple.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/proposals/4124-server-auth-simple.md b/proposals/4124-server-auth-simple.md index c9fb8a24ffc..bfe40b6e0d8 100644 --- a/proposals/4124-server-auth-simple.md +++ b/proposals/4124-server-auth-simple.md @@ -19,13 +19,13 @@ Related issues: ### The `m.server.knock` authorization rule -This rule is be inserted after rule 3 in version 11, the check -for `m.room.create`'s content field `m.federate`. +This rule is be inserted after rule 3 in [version 11](https://spec.matrix.org/v1.10/rooms/v11/#authorization-rules), +the check for `m.room.create`'s content field `m.federate`. 1. If the type is `m.server.knock`: 1. If the `state_key` does not contain the server name for the origin server, reject. - 2. If there is existing state for the origin server's `m.server.knock`, reject. + 2. If there is any current state for the origin server's `m.server.knock`, reject. 3. If the origin server's current participation is `permitted`, allow. 4. If the `m.server.knock_rule` is `deny`, reject. 5. If the origin server's current participation is `deny`, reject. @@ -46,7 +46,7 @@ rule 1.2. ### The `m.server.participation` authorization rule -This rule is to be inserted before rule 4 in version 11, +This rule is to be inserted before rule 4 in [version 11](https://spec.matrix.org/v1.10/rooms/v11/#authorization-rules), the check for `m.room.member`, and after the `m.server.knock` rule described in this proposal. @@ -57,8 +57,9 @@ described in this proposal. ### The `m.server.participation` authorization event, `state_key: ${origin_server_name}` -This is an authorization event that is used to authorize events -originating from the server named in the `state_key`. +This is an [authorization event](https://spec.matrix.org/v1.10/server-server-api/#auth-events-selection) +that is used to authorize events originating from the server named in +the `state_key`. `participation` can be one of `permitted` or `deny`. `participation` is protected from redaction. From c55b09847ce3525a5aa0dfbfa8dcbd6a213f80f3 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Wed, 10 Apr 2024 14:04:30 +0100 Subject: [PATCH 12/18] Add rules for setting your own participation. --- proposals/4124-server-auth-simple.md | 29 ++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/proposals/4124-server-auth-simple.md b/proposals/4124-server-auth-simple.md index bfe40b6e0d8..9ddcb5d1ae8 100644 --- a/proposals/4124-server-auth-simple.md +++ b/proposals/4124-server-auth-simple.md @@ -52,8 +52,28 @@ described in this proposal. 1. If the origin server's current `participation` state is not `permitted`: 1. If the `participation` state is `deny`, reject. - 2. If the `m.server.knock_rule` is `deny`, reject. - 3. If the `m.server.knock_rule` is anything other than `passive`, reject. + 2. If the sender is the same sender of m.room.create, the state_key + of the considered event is the sender's origin server, and the + `participation` field of the considered event is `permitted`, + then allow. + 3. If the sender's origin server matches the state_key of the + considered event, and the `participation` field of the considered + event is not `permitted`, reject. + 3. If the `m.server.knock_rule` is `deny`, reject. + 4. If the `m.server.knock_rule` is anything other than `passive`, reject. + +We allow the room creator to set their own participation and bypass +the `m.server.knock_rule` provided their server has not been explicitly +denied. This is because we want them to be able to set their +participation at room creation without being unable to do when the +`m.server.knock_rule` is `active`. + +We allow senders to add the `participation` of their own server, +provided that they only do so to `permit` their own server (and not +deny themselves as a footgun). This is useful in cases where a +room has a `passive` `m.server.knock_rule` and the room admins need +to explicitly permit their own servers before changing the knock +rule to `active`. ### The `m.server.participation` authorization event, `state_key: ${origin_server_name}` @@ -138,6 +158,11 @@ that there might be without elaboration is not helpful, I'd need to know how the race works. If there is insistence, then we will embed within the `m.room.create` event. +### Changing the `m.server.knock_rule` from `passive` to `active` or `deny` + +Server admins can unintentionally lock themselves out of their room +unless they are the room creator under the current proposal. + ### Soft failure of messages Servers that had `participation` of `permitted` that are later From d5439dff63d7a5a168bd343edefdf5fb549aefb4 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Wed, 10 Apr 2024 14:32:09 +0100 Subject: [PATCH 13/18] rules typos --- proposals/4124-server-auth-simple.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/proposals/4124-server-auth-simple.md b/proposals/4124-server-auth-simple.md index 9ddcb5d1ae8..2f727bb3351 100644 --- a/proposals/4124-server-auth-simple.md +++ b/proposals/4124-server-auth-simple.md @@ -52,13 +52,14 @@ described in this proposal. 1. If the origin server's current `participation` state is not `permitted`: 1. If the `participation` state is `deny`, reject. - 2. If the sender is the same sender of m.room.create, the state_key - of the considered event is the sender's origin server, and the - `participation` field of the considered event is `permitted`, - then allow. - 3. If the sender's origin server matches the state_key of the - considered event, and the `participation` field of the considered - event is not `permitted`, reject. + 2. If the type is `m.server.participation`: + 1. If the sender is the same sender of m.room.create, the state_key + of the considered event is the sender's origin server, and the + `participation` field of the considered event is `permitted`, + then allow. + 2. If the sender's origin server matches the state_key of the + considered event, and the `participation` field of the considered + event is not `permitted`, reject. 3. If the `m.server.knock_rule` is `deny`, reject. 4. If the `m.server.knock_rule` is anything other than `passive`, reject. From f10370de805d7e9783df33471b8d2c89e0d73fd9 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Wed, 10 Apr 2024 14:36:17 +0100 Subject: [PATCH 14/18] rule clarity --- proposals/4124-server-auth-simple.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/proposals/4124-server-auth-simple.md b/proposals/4124-server-auth-simple.md index 2f727bb3351..e0e59325d1c 100644 --- a/proposals/4124-server-auth-simple.md +++ b/proposals/4124-server-auth-simple.md @@ -52,14 +52,11 @@ described in this proposal. 1. If the origin server's current `participation` state is not `permitted`: 1. If the `participation` state is `deny`, reject. - 2. If the type is `m.server.participation`: - 1. If the sender is the same sender of m.room.create, the state_key - of the considered event is the sender's origin server, and the - `participation` field of the considered event is `permitted`, - then allow. - 2. If the sender's origin server matches the state_key of the - considered event, and the `participation` field of the considered - event is not `permitted`, reject. + 2. If the type is `m.server.participation` and the sender's origin + server matches the state_key of the considered event: + 1. If the `participation` field of the considered event is not + `permitted`, reject. + 2. If the sender is the same sender of m.room.create, then allow. 3. If the `m.server.knock_rule` is `deny`, reject. 4. If the `m.server.knock_rule` is anything other than `passive`, reject. From 74149b25e9ad2c4b1416d492f6b461587cf833b5 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Wed, 10 Apr 2024 15:24:26 +0100 Subject: [PATCH 15/18] mermaid diagrams --- proposals/4124-server-auth-simple.md | 99 ++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/proposals/4124-server-auth-simple.md b/proposals/4124-server-auth-simple.md index e0e59325d1c..1b8a49eae63 100644 --- a/proposals/4124-server-auth-simple.md +++ b/proposals/4124-server-auth-simple.md @@ -145,6 +145,105 @@ We believe that the open choice here should not alone be a reason to block this MSC from consideration. But we will follow up with a clone of the `make_knock` handshake if requested. +## Diagrams + +These diagrams do not specify any behaviour and are provided only to +help explain the proposal. Do not write any part of the specification +based upon the diagram, only what you have read from the authorization +rules. + +### Room creation flow + +```mermaid +--- +title: Room creation as of v1.10 +--- +stateDiagram-v2 + create: Alice creates the room + aliceMembership: Alice joins the room + create --> aliceMembership + alicePL: Alice sends the default power levels event from the createRoom template + aliceMembership --> alicePL + aliceJoinRules: Alice sets the join rules + alicePL --> aliceJoinRules +``` + +```mermaid +--- +title: Room creation with simple server authorization +--- +stateDiagram-v2 + create: Alice creates the room + aliceServerParticipation: Alice permits her server to participate + aliceMembership: Alice joins the room + create --> aliceServerParticipation + aliceServerParticipation --> aliceMembership + alicePL: Alice sends the default power levels event from the createRoom template + aliceMembership --> alicePL + aliceJoinRules: Alice sets the join rules + alicePL --> aliceJoinRules + aliceKnockRule: Alice sets the server knock rule + alicePL --> aliceKnockRule +``` + +### Join flow + +This explains the order of events for joining the room, it does +not explain how the `make_join` handshake is amended. + + +```mermaid +--- +title: Joining the room with "passive" knock rule +--- +stateDiagram-v2 + create: Alice creates the room and sets the knock rule to "passive" + bobJoin: Bob sends a membership event with membership join + create --> bobJoin + bobHey: Bob sends m.room.message "Hello!" + bobJoin --> bobHey + state aliceChoice <> + aliceChoiceText: Alice decides whether to explicitly set Bob's participation + bobHey --> aliceChoiceText + aliceChoiceText --> aliceChoice + aliceDeny: Alice sets Bob's participation to "deny" + alicePermit: Alice sets Bob's participation to "permitted" + aliceImplicit: Alice does not make a decision + aliceChoice --> aliceDeny + aliceChoice --> alicePermit + aliceChoice --> aliceImplicit + bobCoolRoom: Bob sends m.room.message "This is a cool room!" + alicePermit --> bobCoolRoom + aliceImplicit --> bobCoolRoom +``` + +```mermaid +--- +title: Joining the room with "active" knock rule +--- +stateDiagram-v2 + create: Alice creates the room and sets the knock rule to "passive" + bobKnock: Bob sends a knock event for his server + create --> bobKnock + state aliceChoice <> + aliceChoiceText: Alice decides whether to explicitly set Bob's participation + bobKnock --> aliceChoiceText + aliceChoiceText --> aliceChoice + aliceDeny: Alice sets Bob's participation to "deny" + alicePermit: Alice sets Bob's participation to "permitted" + aliceImplicit: Alice does not make a decision + aliceChoice --> aliceDeny + aliceChoice --> alicePermit + aliceChoice --> aliceImplicit + bobJoin: Bob sends a membership event with membership join + bobHello: Bob sends m.room.message "Hello!" + bobCannotParticipate: Bob cannot participate + aliceDeny --> bobCannotParticipate + aliceImplicit --> bobCannotParticipate + alicePermit --> bobJoin + bobJoin --> bobHello +``` + ## Potential issues ### Racing with `m.server.knock_rule`? From 758516260bff599d4b51142bd8cb815efa27ac68 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Wed, 10 Apr 2024 16:44:32 +0100 Subject: [PATCH 16/18] clearer active knock rule diagram --- proposals/4124-server-auth-simple.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/proposals/4124-server-auth-simple.md b/proposals/4124-server-auth-simple.md index 1b8a49eae63..ccedfd38b6f 100644 --- a/proposals/4124-server-auth-simple.md +++ b/proposals/4124-server-auth-simple.md @@ -222,22 +222,22 @@ stateDiagram-v2 title: Joining the room with "active" knock rule --- stateDiagram-v2 - create: Alice creates the room and sets the knock rule to "passive" - bobKnock: Bob sends a knock event for his server + create: @alice#colon;matrix.org creates the room and sets the knock rule to "passive" + bobKnock: @bob#colon;example.com sends a knock event for his server#colon; example.com create --> bobKnock state aliceChoice <> - aliceChoiceText: Alice decides whether to explicitly set Bob's participation + aliceChoiceText: @alice#colon;matrix.org decides whether to explicitly set example.com's participation bobKnock --> aliceChoiceText aliceChoiceText --> aliceChoice - aliceDeny: Alice sets Bob's participation to "deny" - alicePermit: Alice sets Bob's participation to "permitted" - aliceImplicit: Alice does not make a decision + aliceDeny: @alice#colon;matrix.org sets example.com's participation to "deny" + alicePermit: @alice#colon;matrix.org sets example.com's participation to "permitted" + aliceImplicit: @alice#colon;matrix.org does not make a decision aliceChoice --> aliceDeny aliceChoice --> alicePermit aliceChoice --> aliceImplicit - bobJoin: Bob sends a membership event with membership join - bobHello: Bob sends m.room.message "Hello!" - bobCannotParticipate: Bob cannot participate + bobJoin: @bob#colon;example.com sends a membership event with membership join + bobHello: @bob#colon;example.com sends m.room.message "Hello!" + bobCannotParticipate: @bob#colon;example.com cannot participate and example.com
cannot craft any authorizable event anywhere in the DAG aliceDeny --> bobCannotParticipate aliceImplicit --> bobCannotParticipate alicePermit --> bobJoin From de8fbcd24bcec29170725227930530d2f8e89647 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Fri, 12 Apr 2024 15:13:42 +0100 Subject: [PATCH 17/18] Context. --- proposals/4124-server-auth-simple.md | 118 ++++++++++++++++++++++++++- 1 file changed, 117 insertions(+), 1 deletion(-) diff --git a/proposals/4124-server-auth-simple.md b/proposals/4124-server-auth-simple.md index ccedfd38b6f..2cc80a71618 100644 --- a/proposals/4124-server-auth-simple.md +++ b/proposals/4124-server-auth-simple.md @@ -15,6 +15,117 @@ there is enough time to introduce a more complete solution. Related issues: - https://github.com/matrix-org/matrix-spec/issues/928 +## Context + +NOTE: This context was added retroactively + +[Server Access Control Lists](https://spec.matrix.org/v1.10/server-server-api/#server-access-control-lists-acls) +and their associated [event](https://spec.matrix.org/v1.10/client-server-api/#mroomserver_acl), +`m.room.server_acl`, are intended to control which servers can interact +with a Matrix room + +### Problem: ambient room access + +Overwhelmingly server ACL use in the federation is as a +reactive measure to servers which are known to proliferate abuse. +These servers are often added to the `deny` list, and it is the author's +subjective understanding that the majority of public Matrix rooms +use an allow list of `["*"]`. For any room with an `allow` literal of +`["*"]`, servers are given unrestricted authority to interact with +the room, even poison the DAG, before a room administrator is even +aware of the attacking server's existence[^room-admin]. As the +the room admin is unaware of the existence of the attacking server, +this means that they or their tooling will be unable to research +the reputation of the server and determine whether to `deny` them +until an attack is already underway, which is too late. +This is why we are introducing the `m.server.knock_rule` later in this +proposal. DO NOT assume this is comparable to `membership` knocking +until you have read the proposal. + +### Problem: leaky servers + +Server ACLs are specified as restricting which requests a server +can make in relation to a room from the [server-server API](https://spec.matrix.org/v1.10/server-server-api/#server-access-control-lists-acls). + +> The ACLs are applied to servers when they make requests + +> Note: Server ACLs do not restrict the events relative to the room DAG via authorisation rules, but instead act purely at the network layer to determine which servers are allowed to connect and interact with a given room. + +There is one notable exception to this, which is currently +[poorly specified](https://github.com/matrix-org/matrix-spec/issues/1784), +in that when a denied server uses `/federation/v1/send`, any PDUs +that originate from the denied server are failed. Note, these PDUs +are only failed when the denied server is the sender and origin of the +transaction. + +Server ACL is currently effective even when the denied server is not +cooperative. However, if there is a distinct uncooperative server in +the room, the uncooperative server can leak events from the denied +server to all other servers, either by using leaked events as forward +extremities or including them in responses to `/get_missing_events`. + +Mitigating this problem is hard, because as the `m.room.server_acl` +event is specified to restrict servers at the "request" level, +there is no restriction on events themselves. If servers were to +naively apply server ACL to events, they would likely soft fail +all the events that the denied server sent throughout the room's +history. This is because `m.room.server_acl` is intentionally +not specified with any consideration of DAG semantics. We believe +the intention of this is to stop a malicious server being able to add a +boundless number of soft failed events to the DAG. Which we believe +would be possible with current soft fail checks and a DAG based server +access system like the one within this proposal. + +It should be clear that servers can leak events to conforming +implementations unintentionally, depending on whether the implementers +have implemented server access control in a conforming way. + +### Problem: size limit + +It is theorized by me completely from thin air that the server ACL +event can contain roughly `512` entries before a limit to the +event size is reached. A survey of #matrix-org-coc-bl:matrix.org +suggests that most ACL events contain `150`~ deny entries. +However, there have been unstable periods in Matrix's history +due to vulnerability of servers where the number of deny entries +has been much greater. For example, Synapse previously had weak +registration requirements by default that was exploited in a major +incident. There could be a need to protect rooms from vulnerable +servers again in the future. + +### Workaround for ambient room access: explicit allow list + +An explicit allow list can be used to work around the issue of +ambient room access. This means that only servers that are known +to room admins can interact with the room. + +#### Bootstrapping + +This workaround has a bootstrapping problem, because any server, +either well established or completely new will be unable to join +a community unless they can contact room admins or their tooling +out of band to request access. + +For large public rooms with reputation, this is problematic as these +out of band channels to request access are now the next target of abuse. +Typically requesting access in this way requires manual intervention +from the joining user and is slow. + +#### Public Rooms + +This work around represents a serious user experience issue for +both the users and the room administrators public rooms, since +vetting new users is time consuming for both parties. + +### Workaround for leaky servers: banning, kicking, redacting + +A work around for leaky servers is falling back to the existing room +level user controls such as banning, kicking and redacting. +Though it is possible for room administrators to become overwhelmed +if the leaking is part of an intentional attack. They could then +change the join rule for the room, but this would provide a disruption +to their service that outlives the attack. + ## Proposal ### The `m.server.knock` authorization rule @@ -68,7 +179,7 @@ participation at room creation without being unable to do when the We allow senders to add the `participation` of their own server, provided that they only do so to `permit` their own server (and not -deny themselves as a footgun). This is useful in cases where a +deny themselves as a foot gun). This is useful in cases where a room has a `passive` `m.server.knock_rule` and the room admins need to explicitly permit their own servers before changing the knock rule to `active`. @@ -294,3 +405,8 @@ None considered. No direct dependencies See `make_server_knock` handshake. + +[^room-admin]: It is possible to craft and send events initially to +servers that room admins do not reside on. +Though most rooms are probably vulnerable to less than this, +and somewhat simnple spam join attacks. From 4d81894a59023e0d19b451d9e42c7c3c74de2da4 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Fri, 12 Apr 2024 15:24:34 +0100 Subject: [PATCH 18/18] workaround for leak detection. --- proposals/4124-server-auth-simple.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/proposals/4124-server-auth-simple.md b/proposals/4124-server-auth-simple.md index 2cc80a71618..5b27061d1a2 100644 --- a/proposals/4124-server-auth-simple.md +++ b/proposals/4124-server-auth-simple.md @@ -126,6 +126,21 @@ if the leaking is part of an intentional attack. They could then change the join rule for the room, but this would provide a disruption to their service that outlives the attack. +### Theorized workaround for leaky servers: leak detection + +It has been suggested that it is possible to detect a leak by +forensically analyzing the DAG in order to find which servers +are accepting a denied server's events by analyzing which +servers have used them as forward extremities. + +The author does not consider this to be an acceptable workaround, +because it is possible for a malicious leaking server to poison +`/get_missing_events` and other endpoints to get spec conforming +servers to accept events from denied servers without the malicious +leaking server generating any suspicious PDUs themselves. +In this instance, a naive leak detection tool would likely incriminate +the wrong server. + ## Proposal ### The `m.server.knock` authorization rule