From 337c0fb3e1a9b8fca3791b175498ca5026813c7e Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Wed, 23 Nov 2016 14:51:30 -0500 Subject: [PATCH] Add $wgSoftBlockRanges This variable allows for blocking anonymous contributions from certain IP addresses. Account creation from these addresses will be allowed. The idea here is that, for example, Wikimedia could add 10.0.0.0/8 to prevent logged-out bots on labs from making confusing edits. See I74f5f4a3. The default for the new variable is empty to avoid causing issues on upgrade for wikis on private networks. Change-Id: I6c11a6b9e1a740de074e7ccd753418f94c4b6288 --- RELEASE-NOTES-1.29 | 2 ++ includes/DefaultSettings.php | 9 +++++++ includes/user/User.php | 20 ++++++++++++++-- languages/i18n/en.json | 1 + languages/i18n/qqq.json | 1 + tests/phpunit/includes/user/UserTest.php | 30 ++++++++++++++++++++++++ 6 files changed, 61 insertions(+), 2 deletions(-) diff --git a/RELEASE-NOTES-1.29 b/RELEASE-NOTES-1.29 index b8867389be..7c60fa7fb9 100644 --- a/RELEASE-NOTES-1.29 +++ b/RELEASE-NOTES-1.29 @@ -39,6 +39,8 @@ production. downloading the XML dump during a transwiki import in seconds. * Parser limit report is now available in machine-readable format to JavaScript via mw.config.get('wgPageParseReport'). +* Added $wgSoftBlockRanges, to allow for automatically blocking anonymous edits + from certain IP ranges (e.g. private IPs). === External library changes in 1.29 === diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 77061dfcc8..a56c8dfaa8 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -5515,6 +5515,15 @@ $wgDnsBlacklistUrls = [ 'http.dnsbl.sorbs.net.' ]; */ $wgProxyWhitelist = []; +/** + * IP ranges that should be considered soft-blocked (anon-only, account + * creation allowed). The intent is to use this to prevent anonymous edits from + * shared resources such as Wikimedia Labs. + * @since 1.29 + * @var string[] + */ +$wgSoftBlockRanges = []; + /** * Whether to look at the X-Forwarded-For header's list of (potentially spoofed) * IPs and apply IP blocks to them. This allows for IP blocks to work with correctly-configured diff --git a/includes/user/User.php b/includes/user/User.php index 562f0d1e9b..fed64c2a68 100644 --- a/includes/user/User.php +++ b/includes/user/User.php @@ -301,7 +301,8 @@ class User implements IDBAccessObject { protected $queryFlagsUsed = self::READ_NORMAL; /** @var string Indicates type of block (used for eventlogging) - * Permitted values: 'cookie-block', 'proxy-block', 'openproxy-block', 'xff-block' + * Permitted values: 'cookie-block', 'proxy-block', 'openproxy-block', 'xff-block', + * 'config-block' */ public $blockTrigger = false; @@ -1581,7 +1582,7 @@ class User implements IDBAccessObject { * Check when actually saving should be done against master. */ private function getBlockedStatus( $bFromSlave = true ) { - global $wgProxyWhitelist, $wgUser, $wgApplyIpBlocksToXff; + global $wgProxyWhitelist, $wgUser, $wgApplyIpBlocksToXff, $wgSoftBlockRanges; if ( -1 != $this->mBlockedby ) { return; @@ -1680,6 +1681,21 @@ class User implements IDBAccessObject { } } + if ( !$block instanceof Block + && $ip !== null + && $this->isAnon() + && IP::isInRanges( $ip, $wgSoftBlockRanges ) + ) { + $block = new Block( [ + 'address' => $ip, + 'byText' => 'MediaWiki default', + 'reason' => wfMessage( 'softblockrangesreason', $ip )->text(), + 'anonOnly' => true, + 'systemBlock' => 'wgSoftBlockRanges', + ] ); + $this->blockTrigger = 'config-block'; + } + if ( $block instanceof Block ) { wfDebug( __METHOD__ . ": Found block.\n" ); $this->mBlock = $block; diff --git a/languages/i18n/en.json b/languages/i18n/en.json index 4131777a18..a621f1c5b2 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -2480,6 +2480,7 @@ "sorbs": "DNSBL", "sorbsreason": "Your IP address is listed as an open proxy in the DNSBL used by {{SITENAME}}.", "sorbs_create_account_reason": "Your IP address is listed as an open proxy in the DNSBL used by {{SITENAME}}.\nYou cannot create an account.", + "softblockrangesreason": "Anonymous contributions are not allowed from your IP address ($1). Please log in.", "xffblockreason": "An IP address present in the X-Forwarded-For header, either yours or that of a proxy server you are using, has been blocked. The original block reason was: $1", "cant-see-hidden-user": "The user you are trying to block has already been blocked and hidden.\nSince you do not have the hideuser right, you cannot see or edit the user's block.", "ipbblocked": "You cannot block or unblock other users because you are yourself blocked.", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index 78a0f9c43e..7c58284967 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -2664,6 +2664,7 @@ "sorbs": "{{optional}}", "sorbsreason": "See also:\n* {{msg-mw|Sorbsreason}}\n* {{msg-mw|Sorbs create account_reason}}", "sorbs_create_account_reason": "Used in [[Special:UserLogin]] when creating an account.\n\nSee also:\n* {{msg-mw|Sorbsreason}}\n* {{msg-mw|Sorbs create account_reason}}", + "softblockrangesreason": "This text is shown to the user as a block reason and describes that the user is being blocked because the user is not logged in and their IP is in [[mw:Special:MyLanguage/Manual:$wgSoftBlockRanges|$wgSoftBlockRanges]].\n\nParameters:\n* $1 - The IP address that is blocked.", "xffblockreason": "This text is shown to the user as a block reason and describes that the user is being blocked because an IP in the X-Forwarded-For header (which lists the user's IP as well as all IPs of the transparent proxy servers they went through) sent when they loaded the page has been blocked:\n* $1 is the original block reason for the IP address matched in the X-Forwarded-For header", "cant-see-hidden-user": "Used as (red) error message on [[Special:Block]] when you try to change (as sysop without the hideuser right) the block of a hidden user.", "ipbblocked": "Error message shown when a user tries to alter block settings when they are themselves blocked.", diff --git a/tests/phpunit/includes/user/UserTest.php b/tests/phpunit/includes/user/UserTest.php index 5d9cda7c44..47fd56d2fe 100644 --- a/tests/phpunit/includes/user/UserTest.php +++ b/tests/phpunit/includes/user/UserTest.php @@ -752,4 +752,34 @@ class UserTest extends MediaWikiTestCase { // Clean up. $block->delete(); } + + public function testSoftBlockRanges() { + global $wgUser; + + $this->setMwGlobals( [ + 'wgSoftBlockRanges' => [ '10.0.0.0/8' ], + 'wgUser' => null, + ] ); + + // IP isn't in $wgSoftBlockRanges + $request = new FauxRequest(); + $request->setIP( '192.168.0.1' ); + $wgUser = User::newFromSession( $request ); + $this->assertNull( $wgUser->getBlock() ); + + // IP is in $wgSoftBlockRanges + $request = new FauxRequest(); + $request->setIP( '10.20.30.40' ); + $wgUser = User::newFromSession( $request ); + $block = $wgUser->getBlock(); + $this->assertInstanceOf( Block::class, $block ); + $this->assertSame( 'wgSoftBlockRanges', $block->getSystemBlockType() ); + + // Make sure the block is really soft + $request->getSession()->setUser( $this->getTestUser()->getUser() ); + $wgUser = User::newFromSession( $request ); + $this->assertFalse( $wgUser->isAnon(), 'sanity check' ); + $this->assertNull( $wgUser->getBlock() ); + } + } -- 2.20.1