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

Commit 69ab3dd

Browse files
authored
Make check_event_allowed module API callback not fail open (accept events) when an exception is raised (#11033)
1 parent 66bdca3 commit 69ab3dd

File tree

5 files changed

+24
-17
lines changed

5 files changed

+24
-17
lines changed

changelog.d/11033.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Do not accept events if a third-party rule module API callback raises an exception.

docs/modules/third_party_rules_callbacks.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ event with new data by returning the new event's data as a dictionary. In order
4343
that, it is recommended the module calls `event.get_dict()` to get the current event as a
4444
dictionary, and modify the returned dictionary accordingly.
4545

46+
If `check_event_allowed` raises an exception, the module is assumed to have failed.
47+
The event will not be accepted but is not treated as explicitly rejected, either.
48+
An HTTP request causing the module check will likely result in a 500 Internal
49+
Server Error.
50+
51+
When the boolean returned by the module is `False`, the event is rejected.
52+
(Module developers should not use exceptions for rejection.)
53+
4654
Note that replacing the event only works for events sent by local users, not for events
4755
received over federation.
4856

synapse/api/errors.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,3 +596,10 @@ class ShadowBanError(Exception):
596596
597597
This should be caught and a proper "fake" success response sent to the user.
598598
"""
599+
600+
601+
class ModuleFailedException(Exception):
602+
"""
603+
Raised when a module API callback fails, for example because it raised an
604+
exception.
605+
"""

synapse/events/third_party_rules.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import logging
1515
from typing import TYPE_CHECKING, Any, Awaitable, Callable, List, Optional, Tuple
1616

17-
from synapse.api.errors import SynapseError
17+
from synapse.api.errors import ModuleFailedException, SynapseError
1818
from synapse.events import EventBase
1919
from synapse.events.snapshot import EventContext
2020
from synapse.types import Requester, StateMap
@@ -233,9 +233,10 @@ async def check_event_allowed(
233233
# This module callback needs a rework so that hacks such as
234234
# this one are not necessary.
235235
raise e
236-
except Exception as e:
237-
logger.warning("Failed to run module API callback %s: %s", callback, e)
238-
continue
236+
except Exception:
237+
raise ModuleFailedException(
238+
"Failed to run `check_event_allowed` module API callback"
239+
)
239240

240241
# Return if the event shouldn't be allowed or if the module came up with a
241242
# replacement dict for the event.

tests/rest/client/test_third_party_rules.py

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -216,19 +216,9 @@ async def check(ev: EventBase, state):
216216
{"x": "x"},
217217
access_token=self.tok,
218218
)
219-
# check_event_allowed has some error handling, so it shouldn't 500 just because a
220-
# module did something bad.
221-
self.assertEqual(channel.code, 200, channel.result)
222-
event_id = channel.json_body["event_id"]
223-
224-
channel = self.make_request(
225-
"GET",
226-
"/_matrix/client/r0/rooms/%s/event/%s" % (self.room_id, event_id),
227-
access_token=self.tok,
228-
)
229-
self.assertEqual(channel.code, 200, channel.result)
230-
ev = channel.json_body
231-
self.assertEqual(ev["content"]["x"], "x")
219+
# Because check_event_allowed raises an exception, it leads to a
220+
# 500 Internal Server Error
221+
self.assertEqual(channel.code, 500, channel.result)
232222

233223
def test_modify_event(self):
234224
"""The module can return a modified version of the event"""

0 commit comments

Comments
 (0)