From 69176eeacebb8a607465987e2f3560c9dd013c20 Mon Sep 17 00:00:00 2001
From: Kunal Mehta <legoktm@member.fsf.org>
Date: Fri, 13 Jul 2018 08:07:51 -0700
Subject: [PATCH] SECURITY: API: Respect $wgBlockCIDRLimit in action=block

$wgBlockCIDRLimit states how large rangeblocks are allowed to be for IPv4
and IPv6. The API now calls SpecialBlock::validateTarget() to perform
that validation step.

As a minor thing, SpecialBlock::checkUnblockSelf() is now called twice by
the API, but that can probably be cleaned up at another time.

Tests included.

Bug: T199540
Change-Id: Ic7d60240d9ebd9580c0eb3b41e4befceab69bd81
---
 includes/api/ApiBlock.php                   |  5 +++++
 tests/phpunit/includes/api/ApiBlockTest.php | 19 ++++++++++++++++++-
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/includes/api/ApiBlock.php b/includes/api/ApiBlock.php
index ed3d01ce8e..42be38c6fc 100644
--- a/includes/api/ApiBlock.php
+++ b/includes/api/ApiBlock.php
@@ -121,6 +121,11 @@ class ApiBlock extends ApiBase {
 			'PageRestrictions' => $pageRestrictions,
 		];
 
+		$status = SpecialBlock::validateTarget( $params['user'], $user );
+		if ( !$status->isOK() ) {
+			$this->dieStatus( $status );
+		}
+
 		$retval = SpecialBlock::processForm( $data, $this->getContext() );
 		if ( $retval !== true ) {
 			$this->dieStatus( $this->errorArrayToStatus( $retval ) );
diff --git a/tests/phpunit/includes/api/ApiBlockTest.php b/tests/phpunit/includes/api/ApiBlockTest.php
index feafdef7e0..91e691a3d2 100644
--- a/tests/phpunit/includes/api/ApiBlockTest.php
+++ b/tests/phpunit/includes/api/ApiBlockTest.php
@@ -18,6 +18,10 @@ class ApiBlockTest extends ApiTestCase {
 		);
 
 		$this->mUser = $this->getMutableTestUser()->getUser();
+		$this->setMwGlobals( 'wgBlockCIDRLimit', [
+			'IPv4' => 16,
+			'IPv6' => 19,
+		] );
 	}
 
 	protected function getTokens() {
@@ -37,7 +41,6 @@ class ApiBlockTest extends ApiTestCase {
 		$tokens = $this->getTokens();
 
 		$this->assertNotNull( $this->mUser, 'Sanity check' );
-		$this->assertNotSame( 0, $this->mUser->getId(), 'Sanity check' );
 
 		$this->assertArrayHasKey( 'blocktoken', $tokens, 'Sanity check' );
 
@@ -311,4 +314,18 @@ class ApiBlockTest extends ApiTestCase {
 			self::$users['sysop']->getUser()
 		);
 	}
+
+	public function testRangeBlock() {
+		$this->mUser = User::newFromName( '128.0.0.0/16', false );
+		$this->doBlock();
+	}
+
+	/**
+	 * @expectedException ApiUsageException
+	 * @expectedExceptionMessage Range blocks larger than /16 are not allowed.
+	 */
+	public function testVeryLargeRangeBlock() {
+		$this->mUser = User::newFromName( '128.0.0.0/1', false );
+		$this->doBlock();
+	}
 }
-- 
2.19.2

