CVE-2024-34701 (published 2024-05-14T15:39Z)

CreateWiki is Miraheze\'s MediaWiki extension for requesting & creating wikis. It is possible for users to be considered as the requester of a specific wiki request if their local user ID on any wiki in a wiki farm matches the local ID of the requester at the wiki where the wiki request was made. This allows them to go to that request entry\'s on Special:RequestWikiQueue on the wiki where their local user ID matches and take any actions that the wiki requester is allowed to take from there.\n\nCommit 02e0f298f8d35155c39aa74193cb7b867432c5b8 fixes the issue. Important note about the fix: This vulnerability has been fixed by disabling access to the REST API and special pages outside of the wiki configured as the "global wiki" in `$wgCreateWikiGlobalWiki` in a user\'s MediaWiki settings.\n\nAs a workaround, it is possible to disable the special pages outside of one\'s own global wiki by doing something similar to `miraheze/mw-config` commit e5664995fbb8644f9a80b450b4326194f20f9ddc that is adapted to one\'s own setup. As for the REST API, before the fix, there wasn\'t any REST endpoint that allowed one to make writes. Regardless, it is possible to also disable it outside of the global wiki by using `$wgCreateWikiDisableRESTAPI` and `$wgConf` in the configuration for one\'s own wiki farm..


Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/miraheze/CreateWiki
commit_details: repo_url: https://github.com/miraheze/CreateWiki
author: Alex
author_date: 2024-05-03 19:10:34+02:00
msg: T12011: Disable the special pages and API outside of the global wiki (#519)

https://issue-tracker.miraheze.org/T12011
repository: repo_url: https://github.com/miraheze/CreateWiki
repo_name: miraheze/CreateWiki
description: The extension used at Miraheze for requesting & creating wikis
repo_language: PHP
owner: miraheze
file_changes: filename: SpecialCreateWiki.php
change_type: ModificationType.MODIFY
diff: @@ -6,6 +6,7 @@ use Config;
 use FormSpecialPage;
 use Html;
 use MediaWiki\MediaWikiServices;
+use Miraheze\CreateWiki\EntryPointUtils;
 use Miraheze\CreateWiki\Hooks\CreateWikiHookRunner;
 use Miraheze\CreateWiki\WikiManager;
 
@@ -23,6 +24,16 @@ class SpecialCreateWiki extends FormSpecialPage {
 		$this->hookRunner = $hookRunner;
 	}
 
+	public function execute( $par ) {
+		if ( !EntryPointUtils::currentWikiIsGlobalWiki() ) {
+			return $this->getOutput()->addHTML(
+				Html::errorBox( $this->msg( 'createwiki-wikinotglobalwiki' )->escaped() )
+			);
+		}
+
+		parent::execute( $par );
+	}
+
 	protected function getFormFields() {
 		$par = $this->par;
 		$request = $this->getRequest();

programming_language: PHP
filename: EntryPointUtils.php
change_type: ModificationType.ADD
diff: @@ -0,0 +1,17 @@
+<?php
+namespace Miraheze\CreateWiki;
+
+use MediaWiki\MediaWikiServices;
+use MediaWiki\WikiMap\WikiMap;
+
+class EntryPointUtils {
+
+	public static function currentWikiIsGlobalWiki(): bool {
+		$config = MediaWikiServices::getInstance()->getConfigFactory()->makeConfig( 'CreateWiki' );
+		if ( $config->get( 'CreateWikiGlobalWiki' ) === WikiMap::getCurrentWikiId() ) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+}

programming_language: PHP
filename: RestWikiRequest.php
change_type: ModificationType.MODIFY
diff: @@ -6,6 +6,7 @@ use Config;
 use MediaWiki\Config\ConfigFactory;
 use MediaWiki\Rest\SimpleHandler;
 use MediaWiki\User\UserFactory;
+use Miraheze\CreateWiki\RestUtils;
 use Wikimedia\Message\MessageValue;
 use Wikimedia\ParamValidator\ParamValidator;
 use Wikimedia\Rdbms\ILBFactory;
@@ -41,9 +42,7 @@ class RestWikiRequest extends SimpleHandler {
 	}
 
 	public function run( $requestID ) {
-		if ( $this->config->get( 'CreateWikiDisableRESTAPI' ) ) {
-			return $this->getResponseFactory()->createLocalizedHttpError( 403, new MessageValue( 'createwiki-rest-disabled' ) );
-		}
+		RestUtils::checkEnv();
 		// Should be kept in sync with RequestWikiRequestViewer's $visibilityConds
 		$visibilityConds = [
 			0 => 'public',

programming_language: PHP
filename: RestWikiRequestsByUser.php
change_type: ModificationType.MODIFY
diff: @@ -6,6 +6,7 @@ use Config;
 use MediaWiki\Config\ConfigFactory;
 use MediaWiki\Rest\SimpleHandler;
 use MediaWiki\User\UserFactory;
+use Miraheze\CreateWiki\RestUtils;
 use Wikimedia\Message\MessageValue;
 use Wikimedia\ParamValidator\ParamValidator;
 use Wikimedia\Rdbms\ILBFactory;
@@ -41,9 +42,7 @@ class RestWikiRequestsByUser extends SimpleHandler {
 	}
 
 	public function run( $userName ) {
-		if ( $this->config->get( 'CreateWikiDisableRESTAPI' ) ) {
-			return $this->getResponseFactory()->createLocalizedHttpError( 403, new MessageValue( 'createwiki-rest-disabled' ) );
-		}
+		RestUtils::checkEnv();
 		// Should be kept in sync with RequestWikiRequestViewer's $visibilityConds
 		$visibilityConds = [
 			0 => 'public',

programming_language: PHP
filename: SpecialRequestWiki.php
change_type: ModificationType.MODIFY
diff: @@ -12,6 +12,7 @@ use ManualLogEntry;
 use MediaWiki\MediaWikiServices;
 use Miraheze\CreateWiki\CreateWikiRegexConstraint;
 use Miraheze\CreateWiki\Hooks\CreateWikiHookRunner;
+use Miraheze\CreateWiki\EntryPointUtils;
 use Title;
 
 class SpecialRequestWiki extends FormSpecialPage {
@@ -29,6 +30,12 @@ class SpecialRequestWiki extends FormSpecialPage {
 	}
 
 	public function execute( $par ) {
+		if ( !EntryPointUtils::currentWikiIsGlobalWiki() ) {
+			return $this->getOutput()->addHTML(
+				Html::errorBox( $this->msg( 'createwiki-wikinotglobalwiki' )->escaped() )
+			);
+		}
+
 		$request = $this->getRequest();
 		$out = $this->getOutput();
 

programming_language: PHP
filename: SpecialRequestWikiQueue.php
change_type: ModificationType.MODIFY
diff: @@ -2,8 +2,10 @@
 
 namespace Miraheze\CreateWiki\RequestWiki;
 
+use Html;
 use HTMLForm;
 use Miraheze\CreateWiki\Hooks\CreateWikiHookRunner;
+use Miraheze\CreateWiki\EntryPointUtils;
 use SpecialPage;
 
 class SpecialRequestWikiQueue extends SpecialPage {
@@ -18,6 +20,12 @@ class SpecialRequestWikiQueue extends SpecialPage {
 	}
 
 	public function execute( $par ) {
+		if ( !EntryPointUtils::currentWikiIsGlobalWiki() ) {
+			return $this->getOutput()->addHTML(
+				Html::errorBox( $this->msg( 'createwiki-wikinotglobalwiki' )->escaped() )
+			);
+		}
+
 		$this->setHeaders();
 
 		if ( $par === null || $par === '' ) {

programming_language: PHP
filename: RestUtils.php
change_type: ModificationType.ADD
diff: @@ -0,0 +1,24 @@
+<?php
+
+namespace Miraheze\CreateWiki;
+
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Rest\LocalizedHttpException;
+use Miraheze\CreateWiki\EntryPointUtils;
+use Wikimedia\Message\MessageValue;
+
+class RestUtils {
+
+	/*
+	 * Called from the REST handlers, checks that the current wiki is the global wiki and that the REST API is not disabled
+	 */
+	public static function checkEnv() {
+		if ( !EntryPointUtils::currentWikiIsGlobalWiki() ) {
+			throw new LocalizedHttpException( new MessageValue( 'createwiki-wikinotglobalwiki' ), 403 );
+		}
+		$config = MediaWikiServices::getInstance()->getConfigFactory()->makeConfig( 'CreateWiki' );
+		if ( $config->get( 'CreateWikiDisableRESTAPI' ) ) {
+			throw new LocalizedHttpException( new MessageValue( 'createwiki-rest-disabled' ), 403 );
+		}
+	}
+}

programming_language: PHP
filename: SpecialRequestWikiTest.php
change_type: ModificationType.MODIFY
diff: @@ -5,6 +5,7 @@ namespace Miraheze\CreateWiki\Tests;
 use DerivativeContext;
 use ErrorPageError;
 use MediaWikiIntegrationTestCase;
+use MediaWiki\WikiMap\WikiMap;
 use Miraheze\CreateWiki\Hooks\CreateWikiHookRunner;
 use Miraheze\CreateWiki\RequestWiki\SpecialRequestWiki;
 use SpecialPage;
@@ -33,6 +34,7 @@ class SpecialRequestWikiTest extends MediaWikiIntegrationTestCase {
 	 * @covers ::execute
 	 */
 	public function testExecuteNotLoggedIn() {
+		$this->setMwGlobals( 'wgCreateWikiGlobalWiki', WikiMap::getCurrentWikiId() );
 		$hookRunner = $this->createMock( CreateWikiHookRunner::class );
 		$specialRequestWiki = new SpecialRequestWiki( $hookRunner );
 
@@ -70,6 +72,7 @@ class SpecialRequestWikiTest extends MediaWikiIntegrationTestCase {
 	 * @covers ::execute
 	 */
 	public function testExecuteLoggedInEmailNotConfirmed() {
+		$this->setMwGlobals( 'wgCreateWikiGlobalWiki', WikiMap::getCurrentWikiId() );
 		$this->setGroupPermissions( 'user', 'requestwiki', true );
 
 		$hookRunner = $this->createMock( CreateWikiHookRunner::class );

programming_language: PHP
repo_url: https://github.com/miraheze/mw-config
commit_details: repo_url: https://github.com/miraheze/mw-config
author: Alex
author_date: 2024-05-01 20:03:07+02:00
msg: Add wgCreateWikiDisableRESTAPI (#5549)
repository: repo_url: https://github.com/miraheze/mw-config
repo_name: miraheze/mw-config
description: Production MediaWiki configuration
repo_language: PHP
owner: miraheze
file_changes: filename: LocalSettings.php
change_type: ModificationType.MODIFY
diff: @@ -928,6 +928,11 @@ $wgConf->settings += [
 		'default' => 'wiki',
 		'mirabeta' => 'wikibeta',
 	],
+	'wgCreateWikiDisableRESTAPI' => [
+		'default' => true,
+		'metawiki' => false,
+		'metawikibeta' => false,
+	],
 	'wgCreateWikiGlobalWiki' => [
 		'default' => 'metawiki',
 		'mirabeta' => 'metawikibeta',

programming_language: PHP
repo_url: https://github.com/miraheze/mw-config
commit_details: repo_url: https://github.com/miraheze/mw-config
author: Alex
author_date: 2024-05-03 12:53:33+02:00
msg: T12102: Disable CreateWiki's special pages outside of the global wikis (#5551)
repository: repo_url: https://github.com/miraheze/mw-config
repo_name: miraheze/mw-config
description: Production MediaWiki configuration
repo_language: PHP
owner: miraheze
file_changes: filename: GlobalSettings.php
change_type: ModificationType.MODIFY
diff: @@ -3,6 +3,7 @@
 use MediaWiki\Auth\LocalPasswordPrimaryAuthenticationProvider;
 use MediaWiki\Extension\ConfirmEdit\Store\CaptchaCacheStore;
 use MediaWiki\Html\Html;
+use MediaWiki\SpecialPage\DisabledSpecialPage;
 use MediaWiki\SpecialPage\SpecialPage;
 use Miraheze\MirahezeMagic\MirahezeIRCRCFeedFormatter;
 
@@ -26,6 +27,12 @@ if ( $wmgMirahezeContactPageFooter && $wi->isExtensionActive( 'ContactPage' ) )
 	};
 }
 
+if ( $wi->dbname !== 'metawiki' && $wi->dbname !== 'metawikibeta' ) {
+	$wgSpecialPages['RequestWikiQueue'] = DisabledSpecialPage::getCallback( 'RequestWikiQueue', 'createwiki-requestwikiqueue-disabled' );
+	$wgSpecialPages['RequestWiki'] = DisabledSpecialPage::getCallback( 'RequestWiki', 'createwiki-requestwiki-disabled' );
+	$wgSpecialPages['CreateWiki'] = DisabledSpecialPage::getCallback( 'CreateWiki', 'createwiki-createwiki-disabled' );
+}
+
 // Extensions
 if ( $wi->dbname !== 'ldapwikiwiki' && $wi->dbname !== 'srewiki' ) {
 	wfLoadExtensions( [

programming_language: PHP