Account data events are validated inconsistently
We do not perform any validation when persisting account data events to the database, and treat them as arbitrary JSON. When a user joins a room with a predecessor, we attempt to copy all account_data associated with the predecessor room here. While doing this, we attempt to parse account data events of specific types with ruma. If the events are not valid according to ruma's schema, we return an error and fail to join the room. Because we don't do any validation on the data when it enters the db, writing invalid events can leave a user in a state where they cannot join any upgraded rooms, or cannot join specific upgraded rooms.
The event types that we attempt to copy are global m.direct
events and room-specific m.tag
events. For m.tag
, we don't actually do anything with the event contents and can replace the current logic with an implementation that doesn't validate the contents easily. For m.direct
, we read the set of previous rooms, and add the new room to the set if it's predecessor was present.
The correct fix is likely either to:
- validate some types of account_data events before persisting them to the db
- modify the room upgrade logic to tolerate arbitrary contents in account data events
Note that if we take the first approach (validate before persisting), we need to consider that we may expand the set of events that we need to be valid for room upgrades in the future, and that there may already be invalid events persisted to the db before the validation was added.
I couldn't find anything in the spec discussing copying account data for tombstoned rooms. The section I read was here.
There was some discussion of this problem on matrix here.