diff --git a/changelog.d/13125.feature b/changelog.d/13125.feature
new file mode 100644
index 0000000000..9b0f609541
--- /dev/null
+++ b/changelog.d/13125.feature
@@ -0,0 +1 @@
+Add a rate limit for local users sending invites.
\ No newline at end of file
diff --git a/synapse/config/ratelimiting.py b/synapse/config/ratelimiting.py
index d4090a1f9a..4fc1784efe 100644
--- a/synapse/config/ratelimiting.py
+++ b/synapse/config/ratelimiting.py
@@ -136,6 +136,11 @@ class RatelimitConfig(Config):
defaults={"per_second": 0.003, "burst_count": 5},
)
+ self.rc_invites_per_issuer = RateLimitConfig(
+ config.get("rc_invites", {}).get("per_issuer", {}),
+ defaults={"per_second": 0.3, "burst_count": 10},
+ )
+
self.rc_third_party_invite = RateLimitConfig(
config.get("rc_third_party_invite", {}),
defaults={
diff --git a/synapse/handlers/room_member.py b/synapse/handlers/room_member.py
index bf6bae1232..5648ab4bf4 100644
--- a/synapse/handlers/room_member.py
+++ b/synapse/handlers/room_member.py
@@ -101,19 +101,33 @@ class RoomMemberHandler(metaclass=abc.ABCMeta):
burst_count=hs.config.ratelimiting.rc_joins_remote.burst_count,
)
+ # Ratelimiter for invites, keyed by room (across all issuers, all
+ # recipients).
self._invites_per_room_limiter = Ratelimiter(
store=self.store,
clock=self.clock,
rate_hz=hs.config.ratelimiting.rc_invites_per_room.per_second,
burst_count=hs.config.ratelimiting.rc_invites_per_room.burst_count,
)
- self._invites_per_user_limiter = Ratelimiter(
+
+ # Ratelimiter for invites, keyed by recipient (across all rooms, all
+ # issuers).
+ self._invites_per_recipient_limiter = Ratelimiter(
store=self.store,
clock=self.clock,
rate_hz=hs.config.ratelimiting.rc_invites_per_user.per_second,
burst_count=hs.config.ratelimiting.rc_invites_per_user.burst_count,
)
+ # Ratelimiter for invites, keyed by issuer (across all rooms, all
+ # recipients).
+ self._invites_per_issuer_limiter = Ratelimiter(
+ store=self.store,
+ clock=self.clock,
+ rate_hz=hs.config.ratelimiting.rc_invites_per_issuer.per_second,
+ burst_count=hs.config.ratelimiting.rc_invites_per_issuer.burst_count,
+ )
+
self._third_party_invite_limiter = Ratelimiter(
store=self.store,
clock=self.clock,
@@ -258,7 +272,9 @@ class RoomMemberHandler(metaclass=abc.ABCMeta):
if room_id:
await self._invites_per_room_limiter.ratelimit(requester, room_id)
- await self._invites_per_user_limiter.ratelimit(requester, invitee_user_id)
+ await self._invites_per_recipient_limiter.ratelimit(requester, invitee_user_id)
+ if requester is not None:
+ await self._invites_per_issuer_limiter.ratelimit(requester)
async def _local_membership_update(
self,
|