From 6733992fda2c0b7b58e1ddd61610a5badf7d98ed Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Thu, 16 Feb 2023 20:20:27 +0100 Subject: [PATCH 1/3] MSC3968: Poorer features --- proposals/3968-poorer-features.md | 233 ++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 proposals/3968-poorer-features.md diff --git a/proposals/3968-poorer-features.md b/proposals/3968-poorer-features.md new file mode 100644 index 00000000000..6890f22c216 --- /dev/null +++ b/proposals/3968-poorer-features.md @@ -0,0 +1,233 @@ +# MSC3968: Poorer features + +Matrix owes its name to its aim to interoperate with many protocols, by being supporting a superset +of their individual features. While this is great to bridge events from other protocols to Matrix, +this causes friction in the other direction, as events need to be either converted to a fallback +(that may not be natural to the target platform) or silently dropped altogether. + +Additionally, room administrators may also prefer to forbid some features in order to ease moderation, +cater to specific needs of their community, or provide a different experience of Matrix. + +This MSC aims to provide a way for bridges and room administrators to signal which features senders +should avoid using. This allows clients to hide elements from their UI, provide an error or warning +early to the user, or themselves fallback using any extra context they may have. + + +## Proposal + +This MSC introduces a new `m.room.event_features` state event type, which associates a desirability +level to: + +- attachment mimetypes for `m.file`, `m.audio`, `m.video`, ... events; +- `msgtype` values +- (for clients implementing [MSC1767][MSC1767]) to mimetypes used in extensible events; +- keys in `"content"` objects; +- HTML elements + +Mimetypes, msgtype values, keys, and HTML element names are jointly referred to as "entities" below. + + +### Desirability level + +This level is an integer, whose values are defined as: + +- under -100: this entity is forbidden, and must not be sent in any case. + Clients receiving events containing them should hide them from their users + (or display these events without as if they didn't contain the entity) +- from -100 to -1: this entity is discouraged, and should not be sent unless there is + no alternative. + Clients receiving these events may hide them from their users + (or display these events without as if they didn't contain the entity) +- 0 to 100: this entity is acceptable +- over 100: currently undefined, and should be interpreted as 100 + + +Unlike `m.room.power_levels`, `m.room.event_features` acts on event content, so it is enforced +primarily by receiving clients. + +Servers may apply restrictions before sending unencrypted events, and return `M_FORBIDDEN` +in case the event contains an entity with a level under 0. +Receiving servers may hide such events from their clients. + + +### Format of `m.room.event_features` + +`m.room.event_features` events may have these keys: + +- `attachment_mimetypes` (object with integer values): This is a mapping from file mimetypes + to desirability level +- `attachment_mimetypes_default` (integer): the default desirability level for file mimetypes + Can be overridden by the `content_mimetypes` key. Defaults to 0 if unspecified. +- `content_mimetypes` (object with integer values): This is a mapping from content mimetype + (as per MSC1767) to desirability level +- `content_mimetypes_default` (integer): the default desirability level for content mimetypes + (as per MSC1767). `*` may be used as a wildcard. + Can be overridden by the `content_mimetypes` key. Defaults to 0 if unspecified. +- `keys` (object with integer values): This is a mapping from key name to desirability level +- `keys_default` (integer): the default desirability level for keys. + Can be overridden by the `keys` key. Defaults to 0 if unspecified. +- `html_elements` (object with integer values): This is a mapping from HTML element name to desirability level +- `html_elements_default` (integer): the default desirability level for HTML elements. + Can be overridden by the `html_elements` key. Defaults to 0 if unspecified. +- `msgtypes` (object with integer values): This is a mapping from `msgtype` of `m.room.message` + events to desirability level +- `msgtypes_default` (integer): the default desirability level for values of `msgtype` + in `m.room.message` events. + Can be overridden by the `msgtypes` key. Defaults to 0 if unspecified. + +Values not matching these types and undefined keys should be ignored. + +`m.room.event_features` events with a non-empty state key should be ignored. + + +### Examples + + +#### matrix-appservice-irc + +To forbid features known not to gracefully degrade on matrix-appservice-irc +as of 2023-02 (ie. outside RFC1459 and sending files), that is: + +```json5 +{ + "content": { + "keys": { + "m.in_reply_to": -50, // replies + "m.new_content": -100, // edits + "m.relates_to": -1, // Other relations are unlikely to be bridged gracefully + // encrypted files: + "file": -100, + "thumbnail_file": -100 + }, + // discourage HTML elements with no counterpart on IRC: + "html_elements_default": -1, + "html_elements": { + "a": 0, + "b": 0, + "code": 0, + "dive": 0, + "font": 0, + "p": 0, + "pre": 0, + "i": 0, + "u": 0, + "span": 0, + "strong": 0, + "em": 0, + "strike": 0 + }, + // forbid text messages which are neither text nor HTML (eg. `m.location`), + // and encourage text messages over media (which IRC users may prefer not to display inline): + "mimetypes_default": -100, + "mimetypes": { + "text/plain": 0, + "text/html": 0 + }, + "msgtypes_default": -100, + "msgtypes": { + "m.audio": 0, + "m.emote": 100, + "m.file": 0, + "m.image": 0, + "m.notice": 100, + "m.text": 100, + "m.video": 0, + "m.server_notice": 0 + } + }, + "sender": "@appservice:example.com", + "state_key": "", + "type": "m.room.event_features" +} +``` + +#### Easing moderation + +Rooms whose moderators cannot listen to content on the fly can forbid them: + +```json5 +{ + "content": { + "mimetypes": { + "audio/*": -100, + "video/*": -100 + }, + "msgtypes": { + "m.audio": -100, + "m.video": -100 + } + }, + "sender": "@room-admin:example.com", + "state_key": "", + "type": "m.room.event_features" +} +``` + + +## Potential issues + +Clients not implementing this MSC will allow their users to send events hidden from other users. +This is already a problem when sending event types not supported by other clients, but in order +to minimize further impact, the following precautions should be taken until this MSC is widely +implemented: + +- room administrators are discouraged from configuring levels under -100 +- developers are discouraged from hiding events matching desirability levels from -100 and -1 + +New/updated `m.room.event_features` state events may race with new events. +Receiving clients/servers should allow a short grace period if possible before hiding +or dropping events. + +When backfilling history backward, clients should consider they may receive a +`m.room.event_features` event that predates events they already received. + + +## Alternatives + +- giving a name to every feature (or use MSC number) and attribute a desirability level to each + of these names. While this makes `m.room.event_features` more readable from developer tools, + it adds an extra burdens on clients and servers to keep track of these names and map them to + entities anyway +- using `"forbidden"`, `"discouraged"`, and `"acceptable"` as levels instead of integers. + This prevents finer grained display rules (eg. receiving clients may choose to hide events matching + levels under -50, because they are "very discouraged" by the administrator) and future + extendability (eg. values over 100 meaning an entity is required). + Integer values also gives sending clients the option to prioritize some UI elements over others, + in order to send "acceptable" entities with higher desirability levels if they have to choose + one over the other (eg. default to picture vs video vs audio recording based on the room). +- Making clients bundle a list of known limits for each bridge and rely on [MSC2346][MSC2346] + to allow them to discover bridges in a room. + This puts a significant maintenance burden on clients, requires users to constantly update + them to match new bridges (or new bridge configurations), may lead to different Matrix clients + showing different sets of events, does not allow room administrators to set arbitrary limits. +- also including event types (eg. to forbid `m.sticker`), but this is better dealt with using + `m.room.power_levels` + + +## Security considerations + +Clients should not expect or rely on servers blocking or hiding "forbidden" or "discouraged" +entities, even when events are not end-to-end encrypted. + +Different clients may see different things (but it is already an issue with `body`/`formatted_body` +or with [MSC1767][MSC1767]), allowing abusers to send messages targeted to certain (classes of) users +via public rooms. +It is therefore recommended for receiving clients and servers not to hide these events from +users with some sort of moderation powers (eg. power-level over 50, or high enough to issue +kicks or redactions). + + +## Unstable prefix + +During development, `org.matrix.msc3968.room.event_features` is to be used +instead of `m.room.event_features`. + + +## Dependencies + +This MSC builds on [MSC1767][MSC1767], though clients not implementing MSC1767 can simply ignore +parts related to mimetypes, as they have nothing to enforce anyway. + + +[MSC1767]: https://github.com/matrix-org/matrix-spec-proposals/pull/1767 +[MSC2346]: https://github.com/matrix-org/matrix-spec-proposals/pull/2346 From 1fdeb3db9fc17a247325851bffa8c11b7b3486ab Mon Sep 17 00:00:00 2001 From: Val Lorentz Date: Mon, 20 Feb 2023 09:00:47 +0100 Subject: [PATCH 2/3] s/dive/div/ Co-authored-by: Hubert Chathi --- proposals/3968-poorer-features.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/3968-poorer-features.md b/proposals/3968-poorer-features.md index 6890f22c216..e3a9a99b273 100644 --- a/proposals/3968-poorer-features.md +++ b/proposals/3968-poorer-features.md @@ -105,7 +105,7 @@ as of 2023-02 (ie. outside RFC1459 and sending files), that is: "a": 0, "b": 0, "code": 0, - "dive": 0, + "div": 0, "font": 0, "p": 0, "pre": 0, From 8e2c16e2a5c99452724f89c16ee5b52d38d23912 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Sun, 26 Feb 2023 08:02:29 +0100 Subject: [PATCH 3/3] Allow non-empty state keys, based on MSC2346. Similarly to MSC3969. --- proposals/3968-poorer-features.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/proposals/3968-poorer-features.md b/proposals/3968-poorer-features.md index e3a9a99b273..6efae502ad6 100644 --- a/proposals/3968-poorer-features.md +++ b/proposals/3968-poorer-features.md @@ -49,6 +49,9 @@ Servers may apply restrictions before sending unencrypted events, and return `M_ in case the event contains an entity with a level under 0. Receiving servers may hide such events from their clients. +If more than one `m.room.event_features` state events are present in a room, clients should +consider the lowest value of each of the desirability levels they define. + ### Format of `m.room.event_features` @@ -77,7 +80,14 @@ Receiving servers may hide such events from their clients. Values not matching these types and undefined keys should be ignored. -`m.room.event_features` events with a non-empty state key should be ignored. +The state key of `m.room.size_limits` events should either follow the format defined +in [MSC2346][MSC2346] when relevant (ie. when the limitation comes from a bridge) +or be empty otherwise (eg. as a wish of room admins). + +When defining a `m.room.event_features` with a non-empty state key, bridges should also +publish a `uk.half-shot.bridge`/`m.bridge` event with the same key; but clients must +be able to gracefully handle the absence of such a state event. + ### Examples @@ -136,7 +146,7 @@ as of 2023-02 (ie. outside RFC1459 and sending files), that is: } }, "sender": "@appservice:example.com", - "state_key": "", + "state_key": "org.matrix.appservice-irc://irc/libera/#example", "type": "m.room.event_features" } ``` @@ -202,6 +212,10 @@ When backfilling history backward, clients should consider they may receive a showing different sets of events, does not allow room administrators to set arbitrary limits. - also including event types (eg. to forbid `m.sticker`), but this is better dealt with using `m.room.power_levels` +- Requiring the `state_key` to be empty, so a single `m.room.event_features` event is valid + at any given time. This can cause event updates to race when two bridges are set up at the + same time; and makes it harder (or impossible) to tear down a (restrictive) bridge without + removing restrictions of other bridges or admins. ## Security considerations @@ -231,3 +245,4 @@ parts related to mimetypes, as they have nothing to enforce anyway. [MSC1767]: https://github.com/matrix-org/matrix-spec-proposals/pull/1767 [MSC2346]: https://github.com/matrix-org/matrix-spec-proposals/pull/2346 +[MSC2346]: https://github.com/matrix-org/matrix-spec-proposals/pull/2346