Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit b6359c2

Browse files
committed
Reject mentions on the C-S API which are invalid.
1 parent 7f02faf commit b6359c2

File tree

2 files changed

+44
-9
lines changed

2 files changed

+44
-9
lines changed

changelog.d/15311.misc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Reject events with an invalid "mentions" property pert [MSC3952](https://github.com/matrix-org/matrix-spec-proposals/pull/3952).

synapse/events/validator.py

+43-9
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@
1616

1717
import jsonschema
1818

19-
from synapse.api.constants import MAX_ALIAS_LENGTH, EventTypes, Membership
19+
from synapse.api.constants import (
20+
MAX_ALIAS_LENGTH,
21+
EventContentFields,
22+
EventTypes,
23+
Membership,
24+
)
2025
from synapse.api.errors import Codes, SynapseError
2126
from synapse.api.room_versions import EventFormatVersions
2227
from synapse.config.homeserver import HomeServerConfig
@@ -88,27 +93,27 @@ def validate_new(self, event: EventBase, config: HomeServerConfig) -> None:
8893
Codes.INVALID_PARAM,
8994
)
9095

91-
if event.type == EventTypes.Retention:
96+
elif event.type == EventTypes.Retention:
9297
self._validate_retention(event)
9398

94-
if event.type == EventTypes.ServerACL:
99+
elif event.type == EventTypes.ServerACL:
95100
if not server_matches_acl_event(config.server.server_name, event):
96101
raise SynapseError(
97102
400, "Can't create an ACL event that denies the local server"
98103
)
99104

100-
if event.type == EventTypes.PowerLevels:
105+
elif event.type == EventTypes.PowerLevels:
101106
try:
102107
jsonschema.validate(
103108
instance=event.content,
104109
schema=POWER_LEVELS_SCHEMA,
105-
cls=plValidator,
110+
cls=POWER_LEVELS_VALIDATOR,
106111
)
107112
except jsonschema.ValidationError as e:
108113
if e.path:
109114
# example: "users_default": '0' is not of type 'integer'
110115
# cast safety: path entries can be integers, if we fail to validate
111-
# items in an array. However the POWER_LEVELS_SCHEMA doesn't expect
116+
# items in an array. However, the POWER_LEVELS_SCHEMA doesn't expect
112117
# to see any arrays.
113118
message = (
114119
'"' + cast(str, e.path[-1]) + '": ' + e.message # noqa: B306
@@ -125,6 +130,19 @@ def validate_new(self, event: EventBase, config: HomeServerConfig) -> None:
125130
errcode=Codes.BAD_JSON,
126131
)
127132

133+
# If the event contains a mentions key, validate it.
134+
if (
135+
EventContentFields.MSC3952_MENTIONS in event.content
136+
and config.experimental.msc3952_intentional_mentions
137+
):
138+
mentions = event.content[EventContentFields.MSC3952_MENTIONS]
139+
try:
140+
jsonschema.validate(
141+
instance=mentions, schema=MENTIONS_SCHEMA, cls=MENTIONS_VALIDATOR
142+
)
143+
except jsonschema.ValidationError as e:
144+
raise SynapseError(400, e.message)
145+
128146
def _validate_retention(self, event: EventBase) -> None:
129147
"""Checks that an event that defines the retention policy for a room respects the
130148
format enforced by the spec.
@@ -252,11 +270,26 @@ def _ensure_state_event(self, event: Union[EventBase, EventBuilder]) -> None:
252270
},
253271
}
254272

273+
MENTIONS_SCHEMA = {
274+
"type": "object",
275+
"properties": {
276+
"user_ids": {
277+
"type": "array",
278+
"items": {
279+
"type": "string",
280+
},
281+
},
282+
"room": {
283+
"type": "boolean",
284+
},
285+
},
286+
}
287+
255288

256289
# This could return something newer than Draft 7, but that's the current "latest"
257290
# validator.
258-
def _create_power_level_validator() -> Type[jsonschema.Draft7Validator]:
259-
validator = jsonschema.validators.validator_for(POWER_LEVELS_SCHEMA)
291+
def _create_validator(schema: JsonDict) -> Type[jsonschema.Draft7Validator]:
292+
validator = jsonschema.validators.validator_for(schema)
260293

261294
# by default jsonschema does not consider a frozendict to be an object so
262295
# we need to use a custom type checker
@@ -268,4 +301,5 @@ def _create_power_level_validator() -> Type[jsonschema.Draft7Validator]:
268301
return jsonschema.validators.extend(validator, type_checker=type_checker)
269302

270303

271-
plValidator = _create_power_level_validator()
304+
POWER_LEVELS_VALIDATOR = _create_validator(POWER_LEVELS_SCHEMA)
305+
MENTIONS_VALIDATOR = _create_validator(MENTIONS_SCHEMA)

0 commit comments

Comments
 (0)