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

Skip the correct visibility checks when checking the visibility of the state at a given event #7066

Merged
merged 7 commits into from
Mar 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions changelog.d/7066.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a bug that would cause Synapse to respond with an error about event visibility if a client tried to request the state of a room at a given token.
2 changes: 1 addition & 1 deletion synapse/handlers/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ def get_state_events(
raise NotFoundError("Can't find event for token %s" % (at_token,))

visible_events = yield filter_events_for_client(
self.storage, user_id, last_events, apply_retention_policies=False
self.storage, user_id, last_events, filter_send_to_client=False
)

event = last_events[0]
Expand Down
65 changes: 35 additions & 30 deletions synapse/visibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def filter_events_for_client(
events,
is_peeking=False,
always_include_ids=frozenset(),
apply_retention_policies=True,
filter_send_to_client=True,
):
"""
Check which events a user is allowed to see. If the user can see the event but its
Expand All @@ -65,10 +65,9 @@ def filter_events_for_client(
events
always_include_ids (set(event_id)): set of event ids to specifically
include (unless sender is ignored)
apply_retention_policies (bool): Whether to filter out events that's older than
allowed by the room's retention policy. Useful when this function is called
to e.g. check whether a user should be allowed to see the state at a given
event rather than to know if it should send an event to a user's client(s).
filter_send_to_client (bool): Whether we're checking an event that's going to be
sent to a client. This might not always be the case since this function can
also be called to check whether a user can see the state at a given point.

Returns:
Deferred[list[synapse.events.EventBase]]
Expand Down Expand Up @@ -96,7 +95,7 @@ def filter_events_for_client(

erased_senders = yield storage.main.are_users_erased((e.sender for e in events))

if apply_retention_policies:
if filter_send_to_client:
room_ids = {e.room_id for e in events}
retention_policies = {}

Expand All @@ -119,30 +118,36 @@ def allowed(event):

the original event if they can see it as normal.
"""
if event.type == "org.matrix.dummy_event":
return None

if not event.is_state() and event.sender in ignore_list:
return None

# Until MSC2261 has landed we can't redact malicious alias events, so for
# now we temporarily filter out m.room.aliases entirely to mitigate
# abuse, while we spec a better solution to advertising aliases
# on rooms.
if event.type == EventTypes.Aliases:
return None

# Don't try to apply the room's retention policy if the event is a state event, as
# MSC1763 states that retention is only considered for non-state events.
if apply_retention_policies and not event.is_state():
retention_policy = retention_policies[event.room_id]
max_lifetime = retention_policy.get("max_lifetime")

if max_lifetime is not None:
oldest_allowed_ts = storage.main.clock.time_msec() - max_lifetime

if event.origin_server_ts < oldest_allowed_ts:
return None
# Only run some checks if these events aren't about to be sent to clients. This is
# because, if this is not the case, we're probably only checking if the users can
# see events in the room at that point in the DAG, and that shouldn't be decided
# on those checks.
if filter_send_to_client:
if event.type == "org.matrix.dummy_event":
return None

if not event.is_state() and event.sender in ignore_list:
return None

# Until MSC2261 has landed we can't redact malicious alias events, so for
# now we temporarily filter out m.room.aliases entirely to mitigate
# abuse, while we spec a better solution to advertising aliases
# on rooms.
if event.type == EventTypes.Aliases:
return None

# Don't try to apply the room's retention policy if the event is a state
# event, as MSC1763 states that retention is only considered for non-state
# events.
if not event.is_state():
retention_policy = retention_policies[event.room_id]
max_lifetime = retention_policy.get("max_lifetime")

if max_lifetime is not None:
oldest_allowed_ts = storage.main.clock.time_msec() - max_lifetime

if event.origin_server_ts < oldest_allowed_ts:
return None

if event.event_id in always_include_ids:
return event
Expand Down