CVE-2024-25109: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: ManageWiki is a MediaWiki extension allowing users to manage wikis. Special:ManageWiki does not escape escape interface messages on the `columns` and `help` keys on the form descriptor. An attacker may exploit this and would have a cross site scripting attack vector. Exploiting this on-wiki requires the `(editinterface)` right. Users should apply the code changes in commits `886cc6b94`, `2ef0f50880`, and `6942e8b2c` to resolve this vulnerability. There are no known workarounds for this vulnerability.
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Published: 2024-02-09T23:15Z
Repository: https://github.com/miraheze/ManageWiki
Language: PHP
Files changed: includes/FormFactory/ManageWikiFormFactoryBuilder.php
Commit date: 2024-02-09 21:41:58 +0100
Commit message: Merge pull request from GHSA-4jr2-jhfm-2r84

* Fix numerous XSS vulnerabilities

See security advisory

* Fix XSS on the namespace subpage
Diff: diff --git a/includes/FormFactory/ManageWikiFormFactoryBuilder.php b/includes/FormFactory/ManageWikiFormFactoryBuilder.php
index 3bf620e6..65703e96 100644
--- a/includes/FormFactory/ManageWikiFormFactoryBuilder.php
+++ b/includes/FormFactory/ManageWikiFormFactoryBuilder.php
@@ -274,12 +274,12 @@ class ManageWikiFormFactoryBuilder {
 			$hasSettings = count( array_diff_assoc( $filteredList, array_keys( $manageWikiSettings ) ) ) > 0;
 
 			$mwRequirements = $ext['requires'] ? ManageWikiRequirements::process( $ext['requires'], $extList, false, $wiki ) : true;
 
 			$help = [];
-			$conflictLabel = wfMessage( 'managewiki-conflicts' )->text();
-			$requiresLabel = wfMessage( 'managewiki-requires' )->text();
+			$conflictLabel = wfMessage( 'managewiki-conflicts' )->escaped();
+			$requiresLabel = wfMessage( 'managewiki-requires' )->escaped();
 
 			if ( $ext['conflicts'] ) {
 				$help[] = "{$conflictLabel} {$ext['conflicts']}<br/>";
 			}
 
@@ -378,11 +378,11 @@ class ManageWikiFormFactoryBuilder {
 				$configs = ManageWikiTypes::process( $config, $disabled, $groupList, 'settings', $set, $value, $name );
 
 				$help = ( $msgHelp->exists() ) ? $msgHelp->escaped() : $set['help'];
 				if ( $set['requires'] ) {
 					$requires = [];
-					$requiresLabel = wfMessage( 'managewiki-requires' )->text();
+					$requiresLabel = wfMessage( 'managewiki-requires' )->escaped();
 
 					foreach ( $set['requires'] as $require => $data ) {
 						if ( is_array( $data ) ) {
 							foreach ( $data as $index => $element ) {
 								if ( is_array( $element ) ) {
@@ -523,14 +523,14 @@ class ManageWikiFormFactoryBuilder {
 						$a['overridedefault'] = $a['overridedefault'][$id] ?? $a['overridedefault']['default'];
 					}
 
 					$configs = ManageWikiTypes::process( $config, $disabled, false, 'namespaces', $a, $namespaceData['additional'][$key] ?? null, false, $a['overridedefault'], $a['type'] );
 
-					$help = ( $msgHelp->exists() ) ? $msgHelp->text() : $a['help'];
+					$help = ( $msgHelp->exists() ) ? $msgHelp->escaped() : $a['help'];
 					if ( $a['requires'] ) {
 						$requires = [];
-						$requiresLabel = wfMessage( 'managewiki-requires' )->text();
+						$requiresLabel = wfMessage( 'managewiki-requires' )->escaped();
 
 						foreach ( $a['requires'] as $require => $data ) {
 							if ( is_array( $data ) ) {
 								foreach ( $data as $index => $element ) {
 									if ( is_array( $element ) ) {
@@ -658,11 +658,11 @@ class ManageWikiFormFactoryBuilder {
 			$assigned = in_array( $perm, $groupData['assignedPermissions'] );
 
 			$formDescriptor["right-{$perm}"] = [
 				'type' => 'check',
 				'label' => $perm,
-				'help' => User::getRightDescription( $perm ),
+				'help' => htmlspecialchars( User::getRightDescription( $perm ) ),
 				'section' => ( $assigned ) ? 'assigned' : 'unassigned',
 				'default' => $assigned,
 				'disabled' => !$ceMW
 			];
 		}

Vulnerable code: 			$conflictLabel = wfMessage( 'managewiki-conflicts' )->text();
			$requiresLabel = wfMessage( 'managewiki-requires' )->text();
					$requiresLabel = wfMessage( 'managewiki-requires' )->text();
					$help = ( $msgHelp->exists() ) ? $msgHelp->text() : $a['help'];
						$requiresLabel = wfMessage( 'managewiki-requires' )->text();
				'help' => User::getRightDescription( $perm ),
Fixed code: 			$conflictLabel = wfMessage( 'managewiki-conflicts' )->escaped();
			$requiresLabel = wfMessage( 'managewiki-requires' )->escaped();
					$requiresLabel = wfMessage( 'managewiki-requires' )->escaped();
					$help = ( $msgHelp->exists() ) ? $msgHelp->escaped() : $a['help'];
						$requiresLabel = wfMessage( 'managewiki-requires' )->escaped();
				'help' => htmlspecialchars( User::getRightDescription( $perm ) ),