Skip to content

Commit d42fce3

Browse files
authored
proposal to move prev_content (#3442)
1 parent 70d6a0f commit d42fce3

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# MSC3442: move the `prev_content` key to `unsigned`
2+
3+
Background: the Client-Server API specification
4+
[documents](https://matrix.org/docs/spec/client_server/r0.6.1#state-event-fields)
5+
a `prev_content` property to be included on state events. It gives the
6+
`content` of the previous state event with the same `type` and `state_key`.
7+
8+
This property does not form part of the "raw" event as sent to federating
9+
homeservers via the Server-Server API; it is added to events served over the
10+
Client-Server API as a service to those clients.
11+
12+
Adding properties at the top level of the event in this way is confusing: it
13+
makes it difficult to understand which properties are part of the raw event,
14+
and which added retrospectively.
15+
16+
It is also inconsistent with other properties which are added by the local
17+
homeserver such as `age`, `redacted_because` and `transaction_id`, which are
18+
returned under `unsigned`: see https://matrix.org/docs/spec/client_server/r0.6.1#room-event-fields.
19+
20+
## Further background information
21+
22+
1. The specification for the [`GET
23+
/_matrix/client/r0/notifications`](https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-notifications)
24+
API is unusual in that it requires `prev_content` to be returned under
25+
`unsigned`.
26+
27+
2. In general, in addition to returning `prev_content` at the top level as
28+
specified, Synapse *also* returns it under `unsigned`, as proposed here.
29+
30+
The exceptions to this are `GET /notifications` and `GET /sync`, where
31+
Synapse returns `prev_content` *only* under `unsigned`. As noted above, this
32+
is compliant with the spec for `/notifications`, but appears to be a spec
33+
violation for `/sync`.
34+
35+
3. Dendrite returns `prev_content` *only* under `unsigned` (and is therefore
36+
theoretically in violation of the spec).
37+
38+
## Proposal
39+
40+
It is proposed that the specification be updated to move the `prev_content`
41+
property to the `unsigned` object, bringing it in line with `age`,
42+
`redacted_because` and `transaction_id`.
43+
44+
This will affect:
45+
* Events returned by the Client-Server API.
46+
* Events sent to Application Services by the Application Services API.
47+
48+
## Potential issues
49+
50+
The proposed change may break compatibility with existing clients and
51+
Application Services.
52+
53+
In practice, any client supporting Dendrite or `/sync` requests via Synapse
54+
must already support the new location, so this is not a breaking change for
55+
such clients. There may be Application Services which rely on `prev_content` at
56+
the top level; however these can be safely updated to use the new location,
57+
since Synapse populates both locations.
58+
59+
The problem can be further mitigated by homeservers populating the key at
60+
*both* locations for as long as they support older versions of the
61+
specification, as Synapse does today.
62+
63+
## Alternatives
64+
65+
1. We could double-down on the existing situation and require that
66+
`prev_content` always be populated at the top level (possibly including
67+
`/notifications`). That is unattractive for the reasons set out in the
68+
introduction to this proposal. Furthermore, in practice it will introduce
69+
*more* compatibility problems, due to the implementations which currently do
70+
not comply with the spec.
71+
72+
2. We could require that homeservers populate the property at *both*
73+
locations. However, setting aside the added complexity for homeserver
74+
implementations, it also increases the chances of a situation as follows:
75+
76+
* Some clients use one property, some use another.
77+
* A homeserver developer tests against a subset of clients, all of which use
78+
one property.
79+
* In consequence, some clients are incompatible with some homeservers.
80+
81+
## Security considerations
82+
83+
When an event is sent over federation, the sending homeserver can freely add
84+
properties to the `unsigned` object, without them being covered by the
85+
hashes or signatures. Some homeserver implementations (including Synapse)
86+
will then pass any such properties on to clients and application services.
87+
88+
In principle then, a malicious or buggy homeserver implementation could add an
89+
incorrect `prev_content` property under `unsigned`, and send it over
90+
federation. A receiving homeserver, implementing the *current* specification,
91+
might pass that property straight through to a client, and the receiving client
92+
would be unable to tell that it was actually incorrectly populated by the
93+
remote homeserver.
94+
95+
This is a more general problem that exists today, and which requires a more
96+
general solution to `unsigned` objects - see
97+
https://github.com/matrix-org/synapse/issues/11080. This proposal does not
98+
materially affect the problem.
99+
100+
## Unstable prefix
101+
102+
No unstable prefix is required, since the behaviour proposed is already
103+
implemented by both Synapse and Dendrite.

0 commit comments

Comments
 (0)