-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Synapse accepts to_device messages to hidden devices #9348
Description
As part of cross-signing, devices for the master, self-signing and user-signing cross-signing keys are created and stored in the devices table.
These devices should not be getting to_device messages sent to them, as they will never be read by any client. It turns out that it is possible to have to_device messages aimed at them in the device_inbox table through the following:
- Clients can directly send
to_devicemessages to one of your cross-signing public keys. These happen to be the device IDs of these hidden devices. Synapse doesn't condition on the device being hidden, and so will accept them. It should be doing so here:
synapse/synapse/storage/databases/main/deviceinbox.py
Lines 499 to 506 in 6633a40
| rows = self.db_pool.simple_select_many_txn( | |
| txn, | |
| table="devices", | |
| keyvalues={"user_id": user_id}, | |
| column="device_id", | |
| iterable=devices, | |
| retcols=("device_id",), | |
| ) |
- Clients often send
to_devicemessages to all devices of a user, by specifying*as the target. Synapse will then create ato_devicemessage for all devices of a user, including hidden ones:
synapse/synapse/storage/databases/main/deviceinbox.py
Lines 486 to 498 in c7b8235
| # Handle wildcard device_ids. | |
| devices = self.db_pool.simple_select_onecol_txn( | |
| txn, | |
| table="devices", | |
| keyvalues={"user_id": user_id}, | |
| retcol="device_id", | |
| ) | |
| message_json = json_encoder.encode(messages_by_device["*"]) | |
| for device_id in devices: | |
| # Add the message for all devices for this user on this | |
| # server. | |
| messages_json_for_user[device_id] = message_json |
These messages were never getting read, and thus piling up in the database forever. In my testing they didn't seem to be using that much space however. Upon removing them for all users on my homeserver and vacuuming the table, the size of Edit: I don't think this is accurate. After deleting over half the table in a different cleanup and REINDEX+VACUUMing I also only dropped after 10MB.device_inbox only went from 3420MB to 3410MB.
Initially presumed as a client-side issue, before we discovered Synapse was at fault: element-hq/element-web#15638
Related: #3599