settings: Add rate limiting for email address changes.

Co-authored-by: Alex Vandiver <alexmv@zulip.com>
This commit is contained in:
Tim Abbott 2021-11-03 15:20:55 -07:00 committed by Tim Abbott
parent f0532aecc8
commit 1cad29fc3a
4 changed files with 22 additions and 0 deletions

View File

@ -194,6 +194,16 @@ class RateLimitTests(ZulipTestCase):
self.do_test_hit_ratelimits(lambda: self.send_api_message(user, "some stuff"))
@rate_limit_rule(1, 5, domain="email_change_by_user")
def test_hit_change_email_ratelimit_as_user(self) -> None:
user = self.example_user("cordelia")
RateLimitedUser(user).clear_history()
emails = ["new-email-{n}@zulip.com" for n in range(1, 8)]
self.do_test_hit_ratelimits(
lambda: self.api_patch(user, "/api/v1/settings", {"email": emails.pop()}),
)
@rate_limit_rule(1, 5, domain="api_by_ip")
def test_hit_ratelimits_as_ip(self) -> None:
self.do_test_hit_ratelimits(self.send_unauthed_api_request)

View File

@ -36,6 +36,7 @@ from zerver.lib.email_validation import (
)
from zerver.lib.exceptions import JsonableError, RateLimited
from zerver.lib.i18n import get_available_language_codes
from zerver.lib.rate_limiter import RateLimitedUser
from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success
from zerver.lib.send_email import FromAddress, send_email
@ -269,6 +270,12 @@ def json_change_settings(
except ValidationError as e:
raise JsonableError(e.message)
ratelimited, time_until_free = RateLimitedUser(
user_profile, domain="email_change_by_user"
).rate_limit()
if ratelimited:
raise RateLimited(time_until_free)
do_start_email_change_process(user_profile, new_email)
if user_profile.full_name != full_name and full_name.strip() != "":

View File

@ -385,6 +385,10 @@ RATE_LIMITING_RULES = {
"authenticate_by_username": [
(1800, 5), # 5 login attempts within 30 minutes
],
"email_change_by_user": [
(3600, 2), # 2 per hour
(86400, 5), # 5 per day
],
"password_reset_form_by_email": [
(3600, 2), # 2 reset emails per hour
(86400, 5), # 5 per day

View File

@ -267,6 +267,7 @@ RATE_LIMITING_RULES: Dict[str, List[Tuple[int, int]]] = {
"api_by_remote_server": [],
"authenticate_by_username": [],
"sends_email_by_ip": [],
"email_change_by_user": [],
"password_reset_form_by_email": [],
}