summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Robertson <davidr@element.io>2023-01-31 10:57:02 +0000
committerGitHub <noreply@github.com>2023-01-31 10:57:02 +0000
commita134e626e43e9c31a4618d4164ba7d6242c0f803 (patch)
tree186eefe970b8f7d493566ec1066672c48928a590
parentPrefer `type(x) is int` to `isinstance(x, int)` (#14945) (diff)
downloadsynapse-a134e626e43e9c31a4618d4164ba7d6242c0f803.tar.xz
Reject boolean power levels (#14944)
* Better test for bad values in power levels events

The previous test only checked that Synapse didn't raise an exception,
but didn't check that we had correctly interpreted the value of the
dodgy power level.

It also conflated two things: bad room notification levels, and bad user
levels. There _is_ logic for converting the latter to integers, but we
should test it separately.

* Check we ignore types that don't convert to int

* Handle `None` values in `notifications.room`

* Changelog

* Also test that bad values are rejected by event auth

* Docstring

* linter scripttttttttt

* Test boolean values in PL content

* Reject boolean power levels

* Changelog
-rw-r--r--changelog.d/14944.bugfix1
-rw-r--r--synapse/event_auth.py4
-rw-r--r--synapse/events/utils.py6
-rw-r--r--synapse/federation/federation_base.py2
4 files changed, 7 insertions, 6 deletions
diff --git a/changelog.d/14944.bugfix b/changelog.d/14944.bugfix
new file mode 100644
index 0000000000..5fe1fb322b
--- /dev/null
+++ b/changelog.d/14944.bugfix
@@ -0,0 +1 @@
+Fix a bug introduced in Synapse v1.64 where boolean power levels were erroneously permitted in [v10 rooms](https://spec.matrix.org/v1.5/rooms/v10/).
diff --git a/synapse/event_auth.py b/synapse/event_auth.py
index c4a7b16413..e0be9f88cc 100644
--- a/synapse/event_auth.py
+++ b/synapse/event_auth.py
@@ -875,11 +875,11 @@ def _check_power_levels(
                 "kick",
                 "invite",
             }:
-                if not isinstance(v, int):
+                if type(v) is not int:
                     raise SynapseError(400, f"{v!r} must be an integer.")
             if k in {"events", "notifications", "users"}:
                 if not isinstance(v, collections.abc.Mapping) or not all(
-                    isinstance(v, int) for v in v.values()
+                    type(v) is int for v in v.values()
                 ):
                     raise SynapseError(
                         400,
diff --git a/synapse/events/utils.py b/synapse/events/utils.py
index 52e4b467e8..ebf8c7ed83 100644
--- a/synapse/events/utils.py
+++ b/synapse/events/utils.py
@@ -648,10 +648,10 @@ def _copy_power_level_value_as_integer(
 ) -> None:
     """Set `power_levels[key]` to the integer represented by `old_value`.
 
-    :raises TypeError: if `old_value` is not an integer, nor a base-10 string
+    :raises TypeError: if `old_value` is neither an integer nor a base-10 string
         representation of an integer.
     """
-    if isinstance(old_value, int):
+    if type(old_value) is int:
         power_levels[key] = old_value
         return
 
@@ -679,7 +679,7 @@ def validate_canonicaljson(value: Any) -> None:
     * Floats
     * NaN, Infinity, -Infinity
     """
-    if isinstance(value, int):
+    if type(value) is int:
         if value < CANONICALJSON_MIN_INT or CANONICALJSON_MAX_INT < value:
             raise SynapseError(400, "JSON integer out of range", Codes.BAD_JSON)
 
diff --git a/synapse/federation/federation_base.py b/synapse/federation/federation_base.py
index 6bd4742140..29fae716f5 100644
--- a/synapse/federation/federation_base.py
+++ b/synapse/federation/federation_base.py
@@ -280,7 +280,7 @@ def event_from_pdu_json(pdu_json: JsonDict, room_version: RoomVersion) -> EventB
         _strip_unsigned_values(pdu_json)
 
     depth = pdu_json["depth"]
-    if not isinstance(depth, int):
+    if type(depth) is not int:
         raise SynapseError(400, "Depth %r not an intger" % (depth,), Codes.BAD_JSON)
 
     if depth < 0: