-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Strip unauthorized fields from unsigned object in events received over federation
#11530
Changes from 13 commits
e5731aa
d3e786d
edc3ebb
e60f9a2
c865eac
bd38e53
c34088a
28b2141
36696da
a3e7258
bdbbbb3
6475c71
e29625b
3451bd4
b8cfe8c
718e168
ae06c9f
f0e9b97
0917991
6f4834c
835a282
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Add functionality to strip the unsignedData object of unauthorized fields in events arriving over federation. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -276,3 +276,110 @@ def test_cross_signing_keys_retry(self): | |
| "ed25519:" + remote_self_signing_key in self_signing_key["keys"].keys(), | ||
| ) | ||
| self.assertTrue(remote_self_signing_key in self_signing_key["keys"].values()) | ||
|
|
||
|
|
||
| class StripUnsignedFromEventsTestCase(MessageAcceptTests): | ||
|
||
| def test_strip_unauthorized_unsigned_values(self): | ||
| most_recent = self.get_success( | ||
| self.homeserver.get_datastore().get_latest_event_ids_in_room(self.room_id) | ||
| )[0] | ||
| federation_event_handler = self.homeserver.get_federation_event_handler() | ||
| event1 = make_event_from_dict( | ||
| { | ||
| "room_id": self.room_id, | ||
| "sender": "@baduser:test.serv", | ||
| "state_key": "@baduser:test.serv", | ||
| "event_id": "$event1:test.serv", | ||
| "depth": 1000, | ||
| "origin_server_ts": 1, | ||
| "type": "m.room.member", | ||
| "origin": "test.servx", | ||
| "content": {"membership": "join"}, | ||
| "auth_events": [], | ||
| "prev_state": [(most_recent, {})], | ||
| "prev_events": [(most_recent, {})], | ||
| "unsigned": {"malicious garbage": "hackz", "more warez": "more hackz"}, | ||
| } | ||
| ) | ||
| self.get_success(federation_event_handler.on_receive_pdu("test.serv", event1)) | ||
|
|
||
| event = self.get_success(self.store.get_event("$event1:test.serv")) | ||
| event_dict = event.get_dict() | ||
| # Make sure unauthorized fields are stripped from unsigned | ||
| self.assertNotIn("more warez", event_dict["unsigned"]) | ||
|
|
||
| def test_strip_event_maintains_allowed_fields(self): | ||
| most_recent = self.get_success( | ||
| self.homeserver.get_datastore().get_latest_event_ids_in_room(self.room_id) | ||
| )[0] | ||
| federation_event_handler = self.homeserver.get_federation_event_handler() | ||
| event2 = make_event_from_dict( | ||
| { | ||
| "room_id": self.room_id, | ||
| "sender": "@baduser:test.serv", | ||
| "state_key": "@baduser:test.serv", | ||
| "event_id": "$event2:test.serv", | ||
| "depth": 1000, | ||
| "origin_server_ts": 1, | ||
| "type": "m.room.member", | ||
| "origin": "test.servx", | ||
| "auth_events": [], | ||
| "prev_state": [(most_recent, {})], | ||
| "prev_events": [(most_recent, {})], | ||
| "content": {"membership": "join"}, | ||
| "unsigned": { | ||
| "malicious garbage": "hackz", | ||
| "more warez": "more hackz", | ||
| "age": 14, | ||
| "invite_room_state": [], | ||
| }, | ||
| } | ||
| ) | ||
| self.get_success( | ||
| federation_event_handler.on_send_membership_event("test.serv", event2) | ||
| ) | ||
|
|
||
| event = self.get_success(self.store.get_event("$event2:test.serv")) | ||
| event_dict = event.get_dict() | ||
| self.assertIn("age", event_dict["unsigned"]) | ||
| self.assertEqual(14, event_dict["unsigned"]["age"]) | ||
| self.assertNotIn("more warez", event_dict["unsigned"]) | ||
| # Invite_room_state is allowed in events of type m.room.member | ||
| self.assertIn("invite_room_state", event_dict["unsigned"]) | ||
| self.assertEqual([], event_dict["unsigned"]["invite_room_state"]) | ||
|
|
||
| def test_strip_event_removes_fields_based_on_event_type(self): | ||
| most_recent = self.get_success( | ||
| self.homeserver.get_datastore().get_latest_event_ids_in_room(self.room_id) | ||
| )[0] | ||
| federation_event_handler = self.homeserver.get_federation_event_handler() | ||
| event3 = make_event_from_dict( | ||
| { | ||
| "room_id": self.room_id, | ||
| "sender": "@baduser:test.serv", | ||
| "state_key": "@baduser:test.serv", | ||
| "event_id": "$event3:test.serv", | ||
| "depth": 1000, | ||
| "origin_server_ts": 1, | ||
| "type": "m.room.power_levels", | ||
| "origin": "test.servx", | ||
| "content": {}, | ||
| "auth_events": [], | ||
| "prev_state": [(most_recent, {})], | ||
| "prev_events": [(most_recent, {})], | ||
| "unsigned": { | ||
| "malicious garbage": "hackz", | ||
| "more warez": "more hackz", | ||
| "age": 14, | ||
| "invite_room_state": [], | ||
| }, | ||
| } | ||
| ) | ||
| self.get_success(federation_event_handler.on_receive_pdu("test.serv", event3)) | ||
|
|
||
| event = self.get_success(self.store.get_event("$event3:test.serv")) | ||
| event_dict = event.get_dict() | ||
| self.assertIn("age", event_dict["unsigned"]) | ||
| # Invite_room_state field is only permitted in event type m.room.member | ||
| self.assertNotIn("invite_room_state", event_dict["unsigned"]) | ||
| self.assertNotIn("more warez", event_dict["unsigned"]) | ||
Uh oh!
There was an error while loading. Please reload this page.