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

Improve validation of field size limits in events. #14664

Merged
merged 16 commits into from
Dec 13, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions synapse/api/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ def error_dict(self, config: Optional["HomeServerConfig"]) -> "JsonDict":
class EventSizeError(SynapseError):
"""An error raised when an event is too big."""

def __init__(self, msg: str, strict: bool):
def __init__(self, msg: str, unpersistable: bool):
"""
strict:
if True, the PDU must not be persisted, not even as a rejected PDU
Expand All @@ -436,7 +436,7 @@ def __init__(self, msg: str, strict: bool):
"""

super().__init__(413, msg, Codes.TOO_LARGE)
self.strict = strict
self.unpersistable = unpersistable


class LoginError(SynapseError):
Expand Down
22 changes: 11 additions & 11 deletions synapse/event_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,36 +385,36 @@ def _check_size_limits(event: "EventBase") -> None:

# Whole PDU check
if len(encode_canonical_json(event.get_pdu_json())) > MAX_PDU_SIZE:
raise EventSizeError("event too large", strict=True)
raise EventSizeError("event too large", unpersistable=True)
reivilibre marked this conversation as resolved.
Show resolved Hide resolved

# Codepoint size check: Synapse always enforced these limits, so apply
# them strictly.
if len(event.user_id) > 255:
raise EventSizeError("'user_id' too large", strict=True)
raise EventSizeError("'user_id' too large", unpersistable=True)
if len(event.room_id) > 255:
raise EventSizeError("'room_id' too large", strict=True)
raise EventSizeError("'room_id' too large", unpersistable=True)
if event.is_state() and len(event.state_key) > 255:
raise EventSizeError("'state_key' too large", strict=True)
raise EventSizeError("'state_key' too large", unpersistable=True)
if len(event.type) > 255:
raise EventSizeError("'type' too large", strict=True)
raise EventSizeError("'type' too large", unpersistable=True)
if len(event.event_id) > 255:
raise EventSizeError("'event_id' too large", strict=True)
raise EventSizeError("'event_id' too large", unpersistable=True)

strict_byte_limits = (
event.room_version not in LENIENT_EVENT_BYTE_LIMITS_ROOM_VERSIONS
)

# Byte size check: if these fail, then be lenient to avoid breaking rooms.
if len(event.user_id.encode("utf-8")) > 255:
raise EventSizeError("'user_id' too large", strict=strict_byte_limits)
raise EventSizeError("'user_id' too large", unpersistable=strict_byte_limits)
if len(event.room_id.encode("utf-8")) > 255:
raise EventSizeError("'room_id' too large", strict=strict_byte_limits)
raise EventSizeError("'room_id' too large", unpersistable=strict_byte_limits)
if event.is_state() and len(event.state_key.encode("utf-8")) > 255:
raise EventSizeError("'state_key' too large", strict=strict_byte_limits)
raise EventSizeError("'state_key' too large", unpersistable=strict_byte_limits)
if len(event.type.encode("utf-8")) > 255:
raise EventSizeError("'type' too large", strict=strict_byte_limits)
raise EventSizeError("'type' too large", unpersistable=strict_byte_limits)
if len(event.event_id.encode("utf-8")) > 255:
raise EventSizeError("'event_id' too large", strict=strict_byte_limits)
raise EventSizeError("'event_id' too large", unpersistable=strict_byte_limits)


def _check_create(event: "EventBase") -> None:
Expand Down
4 changes: 2 additions & 2 deletions synapse/handlers/federation_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -1739,7 +1739,7 @@ async def prep(event: EventBase) -> None:
logger.warning("Rejecting %r because %s", event, e)
context.rejected = RejectedReason.AUTH_ERROR
except EventSizeError as e:
if e.strict:
if e.unpersistable:
# A strict event size error means the event is completely
# unpersistable.
raise e
Expand Down Expand Up @@ -1794,7 +1794,7 @@ async def _check_event_auth(
context.rejected = RejectedReason.AUTH_ERROR
return
except EventSizeError as e:
if e.strict:
if e.unpersistable:
# A strict event size error means the event is completely
# unpersistable.
raise e
Expand Down