From 9a198f8b25134c8a753241ff6e4b625327688579 Mon Sep 17 00:00:00 2001
From: Brian Wolff <bawolff+wn@gmail.com>
Date: Wed, 21 Nov 2018 16:15:28 +0000
Subject: [PATCH] SECURITY: rate-limit and prevent blocked users from changing
 email

This is to counter spam where people use Special:ChangeEmail to
spam people with the confirmation email and using the username
to promote their thing

Bug: T209794
Change-Id: I8b2bd0f60c66f44c91dc78e3512a73e4237df2f3
---
 includes/DefaultSettings.php             |  4 ++++
 includes/specials/SpecialChangeEmail.php | 10 ++++++++++
 2 files changed, 14 insertions(+)

diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index fa95633..a8f13b8 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -5712,6 +5712,10 @@ $wgRateLimits = [
 		'newbie' => [ 5, 86400 ],
 		'user' => [ 20, 86400 ],
 	],
+	'changeemail' => [
+		'ip-all' => [ 10, 3600 ],
+		'user' => [ 4, 86400 ]
+	],
 	// Purging pages
 	'purge' => [
 		'ip' => [ 30, 60 ],
diff --git a/includes/specials/SpecialChangeEmail.php b/includes/specials/SpecialChangeEmail.php
index 8cf64b1..6152ddf 100644
--- a/includes/specials/SpecialChangeEmail.php
+++ b/includes/specials/SpecialChangeEmail.php
@@ -76,6 +76,10 @@ class SpecialChangeEmail extends FormSpecialPage {
 			throw new PermissionsError( 'viewmyprivateinfo' );
 		}
 
+		if ( $user->isBlockedFromEmailuser() ) {
+			throw new UserBlockedError( $user->getBlock() );
+		}
+
 		parent::checkExecutePermissions( $user );
 	}
 
@@ -160,6 +164,12 @@ class SpecialChangeEmail extends FormSpecialPage {
 			return Status::newFatal( 'changeemail-nochange' );
 		}
 
+		// To prevent spam, rate limit adding a new address, but do
+		// not rate limit removing an address.
+		if ( $newaddr !== '' && $user->pingLimiter( 'changeemail' ) ) {
+			return Status::newFatal( 'actionthrottledtext' );
+		}
+
 		$oldaddr = $user->getEmail();
 		$status = $user->setEmailWithConfirmation( $newaddr );
 		if ( !$status->isGood() ) {
-- 
2.8.1
