From e60dad86ba8528d81ffcd1123bf8aa019110bb5d Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Thu, 22 Oct 2015 11:44:31 +0100 Subject: Reject events which are too large SPEC-222 --- synapse/api/auth.py | 22 +++++++++++++++++++++- synapse/api/errors.py | 9 +++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) (limited to 'synapse/api') diff --git a/synapse/api/auth.py b/synapse/api/auth.py index 494c8ac3d4..88445fe999 100644 --- a/synapse/api/auth.py +++ b/synapse/api/auth.py @@ -14,13 +14,14 @@ # limitations under the License. """This module contains classes for authenticating the user.""" +from canonicaljson import encode_canonical_json from signedjson.key import decode_verify_key_bytes from signedjson.sign import verify_signed_json, SignatureVerifyException from twisted.internet import defer from synapse.api.constants import EventTypes, Membership, JoinRules -from synapse.api.errors import AuthError, Codes, SynapseError +from synapse.api.errors import AuthError, Codes, SynapseError, EventSizeError from synapse.types import RoomID, UserID, EventID from synapse.util.logutils import log_function from synapse.util import third_party_invites @@ -64,6 +65,8 @@ class Auth(object): Returns: True if the auth checks pass. """ + self.check_size_limits(event) + try: if not hasattr(event, "room_id"): raise AuthError(500, "Event has no room_id: %s" % event) @@ -131,6 +134,23 @@ class Auth(object): logger.info("Denying! %s", event) raise + def check_size_limits(self, event): + def too_big(field): + raise EventSizeError("%s too large" % (field,)) + + if len(event.user_id) > 255: + too_big("user_id") + if len(event.room_id) > 255: + too_big("room_id") + if event.is_state() and len(event.state_key) > 255: + too_big("state_key") + if len(event.type) > 255: + too_big("type") + if len(event.event_id) > 255: + too_big("event_id") + if len(encode_canonical_json(event.get_pdu_json())) > 65536: + too_big("event") + @defer.inlineCallbacks def check_joined_room(self, room_id, user_id, current_state=None): """Check if the user is currently joined in the room diff --git a/synapse/api/errors.py b/synapse/api/errors.py index d1356eb4d9..b3fea27d0e 100644 --- a/synapse/api/errors.py +++ b/synapse/api/errors.py @@ -119,6 +119,15 @@ class AuthError(SynapseError): super(AuthError, self).__init__(*args, **kwargs) +class EventSizeError(SynapseError): + """An error raised when an event is too big.""" + + def __init__(self, *args, **kwargs): + if "errcode" not in kwargs: + kwargs["errcode"] = Codes.TOO_LARGE + super(EventSizeError, self).__init__(413, *args, **kwargs) + + class EventStreamError(SynapseError): """An error raised when there a problem with the event stream.""" def __init__(self, *args, **kwargs): -- cgit 1.4.1 From 9b6f3bc7423008fa2d66d88227675b5c1c11db48 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Thu, 22 Oct 2015 16:38:03 +0100 Subject: Support filtering events represented as dicts. This is useful because the emphemeral events such as presence and typing are represented as dicts inside synapse. --- synapse/api/filtering.py | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'synapse/api') diff --git a/synapse/api/filtering.py b/synapse/api/filtering.py index 60b6648e0d..522b151c35 100644 --- a/synapse/api/filtering.py +++ b/synapse/api/filtering.py @@ -183,10 +183,29 @@ class Filter(object): Returns: bool: True if the event matches """ + if isinstance(event, dict): + return self.check_fields( + event.get("room_id", None), + event.get("sender", None), + event.get("type", None), + ) + else: + return self.check_fields( + event.room_id, + event.sender, + event.type, + ) + + def check_fields(self, room_id, sender, event_type): + """Checks whether the filter matches the given event fields. + + Returns: + bool: True if the event fields match + """ literal_keys = { - "rooms": lambda v: event.room_id == v, - "senders": lambda v: event.sender == v, - "types": lambda v: _matches_wildcard(event.type, v) + "rooms": lambda v: room_id == v, + "senders": lambda v: sender == v, + "types": lambda v: _matches_wildcard(event_type, v) } for name, match_func in literal_keys.items(): -- cgit 1.4.1 From 4e05aab4f7daa79d3a521f3477f6ade10157350b Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Thu, 22 Oct 2015 17:08:59 +0100 Subject: Don't assume that the event has a room_id or sender --- synapse/api/filtering.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'synapse/api') diff --git a/synapse/api/filtering.py b/synapse/api/filtering.py index 522b151c35..765d1bc9d5 100644 --- a/synapse/api/filtering.py +++ b/synapse/api/filtering.py @@ -191,8 +191,8 @@ class Filter(object): ) else: return self.check_fields( - event.room_id, - event.sender, + getattr(event, "room_id", None), + getattr(event, "sender", None), event.type, ) -- cgit 1.4.1