Disable $wgServer autodetection to prevent cache poisoning attacks
authorKunal Mehta <legoktm@member.fsf.org>
Fri, 19 Jul 2019 04:04:41 +0000 (00:04 -0400)
committerJames D. Forrester <jforrester@wikimedia.org>
Wed, 30 Oct 2019 22:02:14 +0000 (15:02 -0700)
Since MediaWiki 1.18, $wgServer has been automatically set by the web installer
when it generates LocalSettings.php, so this shouldn't be an issue for most
wikis. The CLI installer now supports a --server optional parameter to
specify $wgServer, otherwise it'll be set to 'http://localhost' by default.

Users will see a fatal error pointing them to the on-wiki $wgServer
documentation that I've updated as well.

Originally this functionality was slated for removal in 1.20, but now is
just a good time as any. It also calls into other parts of MediaWiki before
most things are initialized, making it difficult to librarize some code.

Bug: T30798
Bug: T232931
Change-Id: Ia5d616e7fafbab01655067c24c5a3a073b254f21
(cherry picked from commit 03078991c4408b8e4e72cc28584a9d011d9edf72)

RELEASE-NOTES-1.34
includes/DefaultSettings.php
includes/Setup.php
includes/installer/CliInstaller.php
includes/installer/Installer.php
maintenance/install.php

index f3527ed..bea1cba 100644 (file)
@@ -76,6 +76,10 @@ $wgPasswordPolicy['policies']['default']['PasswordNotInLargeBlacklist'] = false;
   containing some HTML markup in metadata. As a result, the $wgAllowTitlesInSVG
   setting is no longer applied and is now always true. Note that MSIE 7 may
   still be able to misinterpret certain malformed PNG files as HTML.
   containing some HTML markup in metadata. As a result, the $wgAllowTitlesInSVG
   setting is no longer applied and is now always true. Note that MSIE 7 may
   still be able to misinterpret certain malformed PNG files as HTML.
+* (T30798) $wgServer must now always be set in LocalSettings.php. This is most
+  likely the case already for any wiki installed after 1.18. The autodetection
+  system was informally deprecated since 1.18 and vulnerable to cache poisoning
+  attacks. Older wikis may need to update their LocalSettings.php file.
 * Introduced $wgVerifyMimeTypeIE to allow disabling the MSIE 6/7 file type
   detection heuristic on upload, which is more conservative than the checks
   that were changed above.
 * Introduced $wgVerifyMimeTypeIE to allow disabling the MSIE 6/7 file type
   detection heuristic on upload, which is more conservative than the checks
   that were changed above.
index ea8b532..e2bbf0e 100644 (file)
@@ -95,15 +95,14 @@ $wgAssumeProxiesUseDefaultProtocolPorts = true;
  * $wgServer = 'http://example.com';
  * @endcode
  *
  * $wgServer = 'http://example.com';
  * @endcode
  *
- * This is usually detected correctly by MediaWiki. If MediaWiki detects the
- * wrong server, it will redirect incorrectly after you save a page. In that
- * case, set this variable to fix it.
+ * This must be set in LocalSettings.php. The MediaWiki installer does this
+ * automatically since 1.18.
  *
  * If you want to use protocol-relative URLs on your wiki, set this to a
  * protocol-relative URL like '//example.com' and set $wgCanonicalServer
  * to a fully qualified URL.
  */
  *
  * If you want to use protocol-relative URLs on your wiki, set this to a
  * protocol-relative URL like '//example.com' and set $wgCanonicalServer
  * to a fully qualified URL.
  */
-$wgServer = WebRequest::detectServer();
+$wgServer = false;
 
 /**
  * Canonical URL of the server, to use in IRC feeds and notification e-mails.
 
 /**
  * Canonical URL of the server, to use in IRC feeds and notification e-mails.
index d450bdd..6b80ae6 100644 (file)
@@ -629,6 +629,15 @@ define( 'MW_SERVICE_BOOTSTRAP_COMPLETE', 1 );
 
 MWExceptionHandler::installHandler();
 
 
 MWExceptionHandler::installHandler();
 
+// T30798: $wgServer must be explicitly set
+if ( $wgServer === false ) {
+       throw new FatalError(
+               '$wgServer must be set in LocalSettings.php. ' .
+               'See <a href="https://www.mediawiki.org/wiki/Manual:$wgServer">' .
+               'https://www.mediawiki.org/wiki/Manual:$wgServer</a>.'
+       );
+}
+
 // T48998: Bail out early if $wgArticlePath is non-absolute
 foreach ( [ 'wgArticlePath', 'wgVariantArticlePath' ] as $varName ) {
        if ( $$varName && !preg_match( '/^(https?:\/\/|\/)/', $$varName ) ) {
 // T48998: Bail out early if $wgArticlePath is non-absolute
 foreach ( [ 'wgArticlePath', 'wgVariantArticlePath' ] as $varName ) {
        if ( $$varName && !preg_match( '/^(https?:\/\/|\/)/', $$varName ) ) {
index 0ff34b0..6f39f01 100644 (file)
@@ -277,7 +277,8 @@ class CliInstaller extends Installer {
        }
 
        protected function envGetDefaultServer() {
        }
 
        protected function envGetDefaultServer() {
-               return null; // Do not guess if installing from CLI
+               // Use a basic value if the user didn't pass in --server
+               return 'http://localhost';
        }
 
        public function dirIsExecutable( $dir, $url ) {
        }
 
        public function dirIsExecutable( $dir, $url ) {
index 091f93b..f84b974 100644 (file)
@@ -1823,6 +1823,10 @@ abstract class Installer {
 
                // Don't try to use any object cache for SessionManager either.
                $GLOBALS['wgSessionCacheType'] = CACHE_NONE;
 
                // Don't try to use any object cache for SessionManager either.
                $GLOBALS['wgSessionCacheType'] = CACHE_NONE;
+
+               // Set a dummy $wgServer to bypass the check in Setup.php, the
+               // web installer will automatically detect it and not use this value.
+               $GLOBALS['wgServer'] = 'https://🌻.invalid';
        }
 
        /**
        }
 
        /**
index 20254b0..bf39fbd 100644 (file)
@@ -60,6 +60,12 @@ class CommandLineInstaller extends Maintenance {
                        false,
                        true
                );
                        false,
                        true
                );
+               $this->addOption(
+                       'server',
+                       'The base URL of the web server the wiki will be on (http://localhost)',
+                       false,
+                       true
+               );
 
                $this->addOption( 'lang', 'The language to use (en)', false, true );
                /* $this->addOption( 'cont-lang', 'The content language (en)', false, true ); */
 
                $this->addOption( 'lang', 'The language to use (en)', false, true );
                /* $this->addOption( 'cont-lang', 'The content language (en)', false, true ); */