Skip to content

Commit 18f4cac

Browse files
Half-ShotmanuroeXiretzauhoreganoadragon453
authored
MSC4278: Media preview controls (#4278)
* add proposal * MSC4278 * Tweak example * Add invite avatars * off|on * invite * s * Update proposals/4278-media-preview-switch.md Co-authored-by: manuroe <manuroe@users.noreply.github.com> * Remove useless text from previous proposal. * Update proposals/4278-media-preview-switch.md Co-authored-by: Xiretza <xiretza@xiretza.xyz> * Apply suggestions from code review Co-authored-by: Xiretza <xiretza@xiretza.xyz> * Update proposals/4278-media-preview-switch.md Co-authored-by: Xiretza <xiretza@xiretza.xyz> * Update proposals/4278-media-preview-switch.md Co-authored-by: Xiretza <xiretza@xiretza.xyz> * specify defaults * Update proposal * rename file * Tidy up media_previews section and applying statement * remove duplication * Clarify private opt-in/ opt-out * tidy * Be clear that we treat unknown values as `off`. * Add statement around blur * Improve `on` statement * tidy statements * Explain resolving levels * Add url preview thumbnails to The List * cleanup * spell * Update proposals/4278-media-preview-controls.md Co-authored-by: Hubert Chathi <hubertc@matrix.org> * comment about symmetry * Explicitly call out missing join_rules * clarify hide/show * add note about fallback * Add note about invites and room account data * Apply suggestions from code review Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Update 4278-media-preview-controls.md --------- Co-authored-by: manuroe <manuroe@users.noreply.github.com> Co-authored-by: Xiretza <xiretza@xiretza.xyz> Co-authored-by: Hubert Chathi <hubertc@matrix.org> Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
1 parent 465e7c3 commit 18f4cac

1 file changed

Lines changed: 252 additions & 0 deletions

File tree

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
# MSC4278: Media preview controls
2+
3+
Matrix caters to a wide variety of networks configurations. Some networks are closed and the users have a high
4+
degree of safety, and other networks are open to the public internet and are inherently less safe. This proposal
5+
aims to give the user more universal control over the content they see on Matrix, starting with media previews.
6+
7+
Most graphical Matrix clients display media in the timeline of a room with a preview. Often these are delivered
8+
without any consent prompt, at least by default. This presents a risk to users who may be joining the network
9+
and do not have the same safety barriers that experienced users may have configured.
10+
11+
With that in mind, this MSC provides a simple switch for users and homeservers to configure a global media preview
12+
preference.
13+
14+
For the purposes of this MSC, the term "undesirable content" refers to images that the user does not want to see,
15+
be it illegal, abusive or otherwise unwanted.
16+
17+
18+
## Proposal
19+
20+
This proposal introduces a new account data key, `m.media_preview_config`.
21+
22+
This key contains the following content.
23+
24+
```json
25+
{
26+
"media_previews": "off|private|on",
27+
"invite_avatars": "off|on"
28+
}
29+
```
30+
31+
### `media_previews`
32+
33+
A "media preview" is defined as any media in a room that may be rendered automatically without explicit
34+
user consent.
35+
36+
Clients SHOULD show show or hide media depending upon this setting, on at least the following content types:
37+
38+
- Media message types `m.image`, `m.video`, `m.file` which all can include thumbnail information or be thumbnailed
39+
by the homeserver.
40+
- The `m.sticker` event type.
41+
- Inline media via `img`.
42+
- Any event which includes thumbnail information or may be thumbnailed by the homeserver.
43+
- URL Preview thumbnails
44+
45+
The above list is not exhaustive. Other MSCs SHOULD take this setting into account when rendering content that could
46+
be considered a media preview, such as [MSC4027](https://github.com/matrix-org/matrix-spec-proposals/pull/4027) (Custom Images in Reactions).
47+
48+
The one exception to the rule for now is user avatars in rooms the user has joined. For the purposes of this MSC,
49+
by joining a room the user *has* consented to seeing the user avatars contained within. See the potential issues
50+
section for a deeper explanation.
51+
52+
### `invite_avatars`
53+
54+
`invite_avatars` refers to any **room** avatar rendered in the client, where the client has a `membership` of `invite`.
55+
56+
This may typically be rendered in the form of an invite dialog, or a room list preview of a room.
57+
58+
The avatar may refer to:
59+
60+
- The `m.room.avatar` state event.
61+
- The inviting user's `avatar_url` from their profile (in the case of a DM).
62+
63+
In *all* cases where an avatar may be rendered for a room invite, the preview MUST be controlled by this setting.
64+
65+
Note while this setting is effectively boolean, we've kept the enum form to have symmetry with `media_previews`
66+
and to allow for future extensions.
67+
68+
### Property value
69+
70+
#### `off`
71+
72+
The client MUST NOT show any previews for any media in affected rooms. Clients will hide the media entirely,
73+
behind a click-to-view prompt, or some other mechanism where a user is either prevented entirely or must consent
74+
to see the media.
75+
76+
Users MAY individually consent to seeing media, for example by clicking on a prompt to show a preview.
77+
If consent is given, the client SHOULD then track that consent and show the media again in the future. The
78+
mechanism for tracking opt-in/opt-out of media is left as an implementation detail.
79+
80+
#### `private`
81+
82+
Previews for media MAY be shown in "private" rooms without a prompt.
83+
A private room is any room where:
84+
85+
- The `m.room.join_rules` state exists
86+
- The `join_rule` key of this state is `invite`, `knock`, `restricted`, `knock_restricted`.
87+
88+
If any other `join_rule` is set, or cannot be determined by the client then the assumption MUST be that the
89+
room is public and previews MUST NOT be shown. Future join rules may be added to this list, but it's critical
90+
that clients adopt a safety first approach here.
91+
92+
Rooms without a `join_rule` are treated as "public". This is because such rooms are rare in practice, and missing
93+
state may be due to a client or server bug. In those cases we want to fail safe, and refuse to display media in rooms
94+
where we cannot be sure of the join rule.
95+
96+
The user MAY still view specific media if the room is "public", and hide media if the room is "private". This could
97+
be provided via a button attached to the event, but is an implementation detail.
98+
99+
Note that this setting has no effect for `invite_avatars`. Avatars can only be `off` or `on` for all invites.
100+
Bad actors can easily send a DM to a user (which would pass the `private` check) containing unwanted
101+
content.
102+
103+
#### `on`
104+
105+
Media SHOULD be shown in any room without a prompt.
106+
107+
Users SHOULD be able to individually hide media, and this preference MUST be respected over any defaults defined in `m.media_preview_config`.
108+
109+
This value is the **default** setting for both properties when no value is set, to keep with the previous defaults.
110+
111+
### Other values
112+
113+
Clients MUST treat any unknown property value in either defined property as `off`. This is to allow the feature
114+
to be extended in the future, without unsupported clients falling back to unsafe behaviours.
115+
116+
### Levels
117+
118+
The account data may exist at both the global and room level. The global setting defines the preference for
119+
all rooms, unless a per-room setting overrides it.
120+
121+
If the client doesn't have access to room level account data, such as for invites then it should just read
122+
from the global account data.
123+
124+
If `m.media_preview_config` is set at both global and room levels, the client MUST prefer the room account data value
125+
over the global account data value. E.g. account data of:
126+
127+
```jsonc
128+
{ // Room-level account data
129+
"media_previews": "on"
130+
}
131+
```
132+
133+
```jsonc
134+
{ // Global account data
135+
"media_previews": "off",
136+
"invite_avatars": "off"
137+
}
138+
```
139+
140+
would resolve to:
141+
142+
```jsonc
143+
{
144+
"media_previews": "on"
145+
"invite_avatars": "off"
146+
}
147+
```
148+
149+
150+
### Notes
151+
152+
Homeservers MAY specify a default value ahead of time for the user, by setting a default
153+
value internally for the account data. The user MUST be able to mutate this value, as it's
154+
considered a safety feature.
155+
156+
Not all clients will respect this configuration initially, and many clients will continue to support
157+
their own variant of this setting in the short term.
158+
159+
## Potential issues
160+
161+
### Holding more state
162+
163+
This requires clients to hold more state about the room than they would do previously to render a room. This may
164+
present a challenge, particularly for mobile clients who may need this information to render push notifications.
165+
166+
### Spaces
167+
168+
A previous version of this MSC also explored the idea of the setting cascading through a space tree, but
169+
it was difficult to design for both because it required clients to hold more state about the room (e.g. traversing
170+
a large amount of state locally to determine the rules) as well as challenges in rendering the setting to users.
171+
172+
A future MSC may explore the possibility of this applying to spaces, but this initial version will operate only
173+
globally and per-room.
174+
175+
However, not having this feature means many rooms may need to apply their own rules.
176+
177+
#### User Avatars
178+
179+
This MSC explicitly rules out controlling room avatars in joined rooms. Conveying to users why avatars are not
180+
rendering, and giving the ability to explicitly opt-in/opt-out of user avatars felt beyond the scope of this MSCs
181+
room focus.
182+
183+
A future MSC may be considered to give greater protection for user avatars.
184+
185+
## Alternatives
186+
187+
This MSC has been iterated on a few times before being published, and several alternatives were considered.
188+
189+
### A well-known property for a global trust policy
190+
191+
This was [originally considered](https://github.com/matrix-org/matrix-spec-proposals/tree/hs/homeserver-content-trust-level)
192+
to change the default policy on a server, so that users on that server would see previews based on their admin's preferences.
193+
194+
This was rejected as it was far too coarse. Expressing a different rule based on the room you are in
195+
was not possible, and wouldn't allow homeservers to store different preferences. Also, confusingly
196+
if the server was a closed registration personal server that happened to federate with the internet
197+
then it would require you to mark your own server as untrusted, which felt wrong in practice.
198+
199+
### Use join rules to determine safety
200+
201+
This is actually part of the proposal under the "private" flag, but this alone wasn't satisfactory for all users. The join
202+
rules have no direct bearing on the content in the room, and bad actors inviting many people to a private room
203+
containing undesirable content would slip under this check.
204+
205+
### Use space membership
206+
207+
Like the above, we could determine that rooms within a trusted space are safe and rooms outside of it are
208+
not. However, this also comes with drawbacks. It would raise the bar for all clients to expose spaces
209+
as a feature in order to make their users safer, and in practice spaces are not fully supported either
210+
by the ecosystem (e.g. Element X) or organisations yet.
211+
212+
### Room state safety flag
213+
214+
Rooms could expose their safeness via a state event, similar to how this proposal does for account data.
215+
However, this would give administrators too much control over your own client experience. It would put the
216+
responsibility on safety on room administrators, who may lack the knowledge or time for proper room configuration.
217+
218+
It also exposes another possible attack where users are invited to a room similar to a phishing attack, and the
219+
room state would override their personal safety settings to deliver undesirable content.
220+
221+
### Trust users you share a DM with
222+
223+
We could seek to trust media if we share a room with a user (e.g. the `m.direct`), which might be a cheap way to
224+
establish a basis of trust for users.
225+
226+
### Blurring previews
227+
228+
One suggestion would be to blur untrusted previews rather than keeping them as off. There are a few ways that this
229+
could be achieved, but each have downsides.
230+
231+
1. Use [MSC2448](https://github.com/matrix-org/matrix-spec-proposals/pull/2448) client-side blurhashes. Would prevent
232+
downloading blocked media but the blurhash is attacker controlled, and can't be trusted for accuracy.
233+
2. Above, but receiver-side calculation. Would require downloading potentially offensive media to the client and is
234+
a non-starter for potentially dangerous content.
235+
3. Server-side generated previews. Does not work for encrypted rooms, and [were ripped out of MSC2448 anyway](https://github.com/matrix-org/matrix-spec-proposals/pull/2448#discussion_r1089753289)
236+
237+
For the moment, hiding media entirely is a simpler and safer solution.
238+
239+
## Security considerations
240+
241+
This property is ultimately held by the homeserver, and a malicious homeserver may expose you to unwanted content. This is
242+
true today, and users should take caution with who they choose to host their account with.
243+
244+
As with all account data properties, the content MUST be validated.
245+
246+
## Unstable prefix
247+
248+
The property MUST use `io.element.msc4278.media_preview_config` while the property is unstable.
249+
250+
## Dependencies
251+
252+
None.

0 commit comments

Comments
 (0)