summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Cloke <clokep@users.noreply.github.com>2023-05-15 15:01:29 -0400
committerGitHub <noreply@github.com>2023-05-15 15:01:29 -0400
commiteb3c1823d8b059073903354facfed81ed41efbce (patch)
tree06cba6d349e0821bb6f6021c40977da8b03a0f94
parentImplement MSC3389 to protect relations from redaction. (#15565) (diff)
downloadsynapse-eb3c1823d8b059073903354facfed81ed41efbce.tar.xz
Reject instead of erroring on invalid membership events. (#15564)
Instead of resulting in an internal server error for invalid events,
return that the event is invalid.
-rw-r--r--changelog.d/15564.bugfix1
-rw-r--r--synapse/event_auth.py17
2 files changed, 12 insertions, 6 deletions
diff --git a/changelog.d/15564.bugfix b/changelog.d/15564.bugfix
new file mode 100644
index 0000000000..667114ba42
--- /dev/null
+++ b/changelog.d/15564.bugfix
@@ -0,0 +1 @@
+Fix a long-standing bug where an invalid membership event could cause an internal server error.
diff --git a/synapse/event_auth.py b/synapse/event_auth.py
index 25898b95a5..b4b43ec4d7 100644
--- a/synapse/event_auth.py
+++ b/synapse/event_auth.py
@@ -1054,10 +1054,15 @@ def _verify_third_party_invite(
     """
     if "third_party_invite" not in event.content:
         return False
-    if "signed" not in event.content["third_party_invite"]:
+    third_party_invite = event.content["third_party_invite"]
+    if not isinstance(third_party_invite, collections.abc.Mapping):
         return False
-    signed = event.content["third_party_invite"]["signed"]
-    for key in {"mxid", "token"}:
+    if "signed" not in third_party_invite:
+        return False
+    signed = third_party_invite["signed"]
+    if not isinstance(signed, collections.abc.Mapping):
+        return False
+    for key in {"mxid", "token", "signatures"}:
         if key not in signed:
             return False
 
@@ -1075,8 +1080,6 @@ def _verify_third_party_invite(
 
     if signed["mxid"] != event.state_key:
         return False
-    if signed["token"] != token:
-        return False
 
     for public_key_object in get_public_keys(invite_event):
         public_key = public_key_object["public_key"]
@@ -1088,7 +1091,9 @@ def _verify_third_party_invite(
                     verify_key = decode_verify_key_bytes(
                         key_name, decode_base64(public_key)
                     )
-                    verify_signed_json(signed, server, verify_key)
+                    # verify_signed_json incorrectly states it wants a dict, it
+                    # just needs a mapping.
+                    verify_signed_json(signed, server, verify_key)  # type: ignore[arg-type]
 
                     # We got the public key from the invite, so we know that the
                     # correct server signed the signed bundle.