diff --git a/synapse/event_auth.py b/synapse/event_auth.py
index 0fc2c4b27e..965cb265da 100644
--- a/synapse/event_auth.py
+++ b/synapse/event_auth.py
@@ -740,6 +740,32 @@ def _check_power_levels(
except Exception:
raise SynapseError(400, "Not a valid power level: %s" % (v,))
+ # Reject events with stringy power levels if required by room version
+ if (
+ event.type == EventTypes.PowerLevels
+ and room_version_obj.msc3667_int_only_power_levels
+ ):
+ for k, v in event.content.items():
+ if k in {
+ "users_default",
+ "events_default",
+ "state_default",
+ "ban",
+ "redact",
+ "kick",
+ "invite",
+ }:
+ if not isinstance(v, int):
+ raise SynapseError(400, f"{v!r} must be an integer.")
+ if k in {"events", "notifications", "users"}:
+ if not isinstance(v, dict) or not all(
+ isinstance(v, int) for v in v.values()
+ ):
+ raise SynapseError(
+ 400,
+ f"{v!r} must be a dict wherein all the values are integers.",
+ )
+
key = (event.type, event.state_key)
current_state = auth_events.get(key)
|