1- // Copyright 2024 New Vector Ltd.
1+ // Copyright 2024, 2025 New Vector Ltd.
22// Copyright 2024 The Matrix.org Foundation C.I.C.
33//
44// SPDX-License-Identifier: AGPL-3.0-only
@@ -18,13 +18,19 @@ pub struct RateLimitingConfig {
1818 /// Account Recovery-specific rate limits
1919 #[ serde( default ) ]
2020 pub account_recovery : AccountRecoveryRateLimitingConfig ,
21+
2122 /// Login-specific rate limits
2223 #[ serde( default ) ]
2324 pub login : LoginRateLimitingConfig ,
25+
2426 /// Controls how many registrations attempts are permitted
2527 /// based on source address.
2628 #[ serde( default = "default_registration" ) ]
2729 pub registration : RateLimiterConfiguration ,
30+
31+ /// Email authentication-specific rate limits
32+ #[ serde( default ) ]
33+ pub email_authentication : EmailauthenticationRateLimitingConfig ,
2834}
2935
3036#[ derive( Clone , Debug , Serialize , Deserialize , JsonSchema , PartialEq ) ]
@@ -37,6 +43,7 @@ pub struct LoginRateLimitingConfig {
3743 /// change their own password.
3844 #[ serde( default = "default_login_per_ip" ) ]
3945 pub per_ip : RateLimiterConfiguration ,
46+
4047 /// Controls how many login attempts are permitted
4148 /// based on the account that is being attempted to be logged into.
4249 /// This can protect against a distributed brute force attack
@@ -58,6 +65,7 @@ pub struct AccountRecoveryRateLimitingConfig {
5865 /// Note: this limit also applies to re-sends.
5966 #[ serde( default = "default_account_recovery_per_ip" ) ]
6067 pub per_ip : RateLimiterConfiguration ,
68+
6169 /// Controls how many account recovery attempts are permitted
6270 /// based on the e-mail address entered into the recovery form.
6371 /// This can protect against causing e-mail spam to one target.
@@ -67,6 +75,35 @@ pub struct AccountRecoveryRateLimitingConfig {
6775 pub per_address : RateLimiterConfiguration ,
6876}
6977
78+ #[ derive( Clone , Debug , Serialize , Deserialize , JsonSchema , PartialEq ) ]
79+ pub struct EmailauthenticationRateLimitingConfig {
80+ /// Controls how many email authentication attempts are permitted
81+ /// based on the source IP address.
82+ /// This can protect against causing e-mail spam to many targets.
83+ #[ serde( default = "default_email_authentication_per_ip" ) ]
84+ pub per_ip : RateLimiterConfiguration ,
85+
86+ /// Controls how many email authentication attempts are permitted
87+ /// based on the e-mail address entered into the authentication form.
88+ /// This can protect against causing e-mail spam to one target.
89+ ///
90+ /// Note: this limit also applies to re-sends.
91+ #[ serde( default = "default_email_authentication_per_address" ) ]
92+ pub per_address : RateLimiterConfiguration ,
93+
94+ /// Controls how many authentication emails are permitted to be sent per
95+ /// authentication session. This ensures not too many authentication codes
96+ /// are created for the same authentication session.
97+ #[ serde( default = "default_email_authentication_emails_per_session" ) ]
98+ pub emails_per_session : RateLimiterConfiguration ,
99+
100+ /// Controls how many code authentication attempts are permitted per
101+ /// authentication session. This can protect against brute-forcing the
102+ /// code.
103+ #[ serde( default = "default_email_authentication_attempt_per_session" ) ]
104+ pub attempt_per_session : RateLimiterConfiguration ,
105+ }
106+
70107#[ derive( Copy , Clone , Debug , Serialize , Deserialize , JsonSchema , PartialEq ) ]
71108pub struct RateLimiterConfiguration {
72109 /// A one-off burst of actions that the user can perform
@@ -193,12 +230,41 @@ fn default_account_recovery_per_address() -> RateLimiterConfiguration {
193230 }
194231}
195232
233+ fn default_email_authentication_per_ip ( ) -> RateLimiterConfiguration {
234+ RateLimiterConfiguration {
235+ burst : NonZeroU32 :: new ( 5 ) . unwrap ( ) ,
236+ per_second : 1.0 / 60.0 ,
237+ }
238+ }
239+
240+ fn default_email_authentication_per_address ( ) -> RateLimiterConfiguration {
241+ RateLimiterConfiguration {
242+ burst : NonZeroU32 :: new ( 3 ) . unwrap ( ) ,
243+ per_second : 1.0 / 3600.0 ,
244+ }
245+ }
246+
247+ fn default_email_authentication_emails_per_session ( ) -> RateLimiterConfiguration {
248+ RateLimiterConfiguration {
249+ burst : NonZeroU32 :: new ( 2 ) . unwrap ( ) ,
250+ per_second : 1.0 / 300.0 ,
251+ }
252+ }
253+
254+ fn default_email_authentication_attempt_per_session ( ) -> RateLimiterConfiguration {
255+ RateLimiterConfiguration {
256+ burst : NonZeroU32 :: new ( 10 ) . unwrap ( ) ,
257+ per_second : 1.0 / 60.0 ,
258+ }
259+ }
260+
196261impl Default for RateLimitingConfig {
197262 fn default ( ) -> Self {
198263 RateLimitingConfig {
199264 login : LoginRateLimitingConfig :: default ( ) ,
200265 registration : default_registration ( ) ,
201266 account_recovery : AccountRecoveryRateLimitingConfig :: default ( ) ,
267+ email_authentication : EmailauthenticationRateLimitingConfig :: default ( ) ,
202268 }
203269 }
204270}
@@ -220,3 +286,14 @@ impl Default for AccountRecoveryRateLimitingConfig {
220286 }
221287 }
222288}
289+
290+ impl Default for EmailauthenticationRateLimitingConfig {
291+ fn default ( ) -> Self {
292+ EmailauthenticationRateLimitingConfig {
293+ per_ip : default_email_authentication_per_ip ( ) ,
294+ per_address : default_email_authentication_per_address ( ) ,
295+ emails_per_session : default_email_authentication_emails_per_session ( ) ,
296+ attempt_per_session : default_email_authentication_attempt_per_session ( ) ,
297+ }
298+ }
299+ }
0 commit comments