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

Commit

Permalink
Reject mentions on the C-S API which are invalid.
Browse files Browse the repository at this point in the history
  • Loading branch information
clokep committed Mar 22, 2023
1 parent 7f02faf commit 7fe45dc
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 9 deletions.
1 change: 1 addition & 0 deletions changelog.d/15311.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Reject events with an invalid "mentions" property pert [MSC3952](https://github.com/matrix-org/matrix-spec-proposals/pull/3952).
52 changes: 43 additions & 9 deletions synapse/events/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@

import jsonschema

from synapse.api.constants import MAX_ALIAS_LENGTH, EventTypes, Membership
from synapse.api.constants import (
MAX_ALIAS_LENGTH,
EventTypes,
Membership,
EventContentFields,
)
from synapse.api.errors import Codes, SynapseError
from synapse.api.room_versions import EventFormatVersions
from synapse.config.homeserver import HomeServerConfig
Expand Down Expand Up @@ -88,27 +93,27 @@ def validate_new(self, event: EventBase, config: HomeServerConfig) -> None:
Codes.INVALID_PARAM,
)

if event.type == EventTypes.Retention:
elif event.type == EventTypes.Retention:
self._validate_retention(event)

if event.type == EventTypes.ServerACL:
elif event.type == EventTypes.ServerACL:
if not server_matches_acl_event(config.server.server_name, event):
raise SynapseError(
400, "Can't create an ACL event that denies the local server"
)

if event.type == EventTypes.PowerLevels:
elif event.type == EventTypes.PowerLevels:
try:
jsonschema.validate(
instance=event.content,
schema=POWER_LEVELS_SCHEMA,
cls=plValidator,
cls=POWER_LEVELS_VALIDATOR,
)
except jsonschema.ValidationError as e:
if e.path:
# example: "users_default": '0' is not of type 'integer'
# cast safety: path entries can be integers, if we fail to validate
# items in an array. However the POWER_LEVELS_SCHEMA doesn't expect
# items in an array. However, the POWER_LEVELS_SCHEMA doesn't expect
# to see any arrays.
message = (
'"' + cast(str, e.path[-1]) + '": ' + e.message # noqa: B306
Expand All @@ -125,6 +130,19 @@ def validate_new(self, event: EventBase, config: HomeServerConfig) -> None:
errcode=Codes.BAD_JSON,
)

# If the event contains a mentions key, validate it.
if (
EventContentFields.MSC3952_MENTIONS in event.content
and config.experimental.msc3952_intentional_mentions
):
mentions = event.content[EventContentFields.MSC3952_MENTIONS]
try:
jsonschema.validate(
instance=mentions, schema=MENTIONS_SCHEMA, cls=MENTIONS_VALIDATOR
)
except jsonschema.ValidationError as e:
raise SynapseError(400, e.message)

def _validate_retention(self, event: EventBase) -> None:
"""Checks that an event that defines the retention policy for a room respects the
format enforced by the spec.
Expand Down Expand Up @@ -252,11 +270,26 @@ def _ensure_state_event(self, event: Union[EventBase, EventBuilder]) -> None:
},
}

MENTIONS_SCHEMA = {
"type": "object",
"properties": {
"user_ids": {
"type": "array",
"items": {
"type": "string",
},
},
"room": {
"type": "boolean",
},
},
}


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

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


plValidator = _create_power_level_validator()
POWER_LEVELS_VALIDATOR = _create_validator(POWER_LEVELS_SCHEMA)
MENTIONS_VALIDATOR = _create_validator(MENTIONS_SCHEMA)

0 comments on commit 7fe45dc

Please sign in to comment.