From: Kunal Mehta Date: Fri, 10 Oct 2014 06:46:12 +0000 (-0700) Subject: Make allowing site-wide styles on restricted special pages a config option X-Git-Tag: 1.31.0-rc.0~13345^2 X-Git-Url: https://git.cyclocoop.org/%7B%24www_url%7Dadmin/compta/banques/?a=commitdiff_plain;h=b2bb4f8bf29ecab9ae8079c5e4a716a668bf78cd;p=lhc%2Fweb%2Fwiklou.git Make allowing site-wide styles on restricted special pages a config option This mostly reverts commit 614d7e5c274d927f99bfc52ac3a1e6c7e5902408. Many wikis use MediaWiki:Common.css and associated pages to create a custom "theme" for their wiki, which would no longer load on login or preference pages, creating an inconsistent UI. This re-adds the difference in module origin for different types (styles, scripts, etc.), and now OutputPage::disallowUserJs() checks the value of the "AllowSiteCSSOnRestrictedPages" config setting to determine whether to allow site-wide CSS styles or not. By default this feature is disabled to be secure by default. Bug: 71621 Change-Id: I1bf4dd1845b6952c3985e179fbea48181ffb8907 --- diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 29d653da24..b779c01b8f 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -3558,6 +3558,19 @@ $wgResourceLoaderStorageEnabled = false; */ $wgResourceLoaderStorageVersion = 1; +/** + * Whether to allow site-wide CSS (MediaWiki:Common.css and friends) on + * restricted pages like Special:UserLogin or Special:Preferences where + * JavaScript is disabled for security reasons. As it is possible to + * execute JavaScript through CSS, setting this to true opens up a + * potential security hole. Some sites may "skin" their wiki by using + * site-wide CSS, causing restricted pages to look unstyled and different + * from the rest of the site. + * + * @since 1.25 + */ +$wgAllowSiteCSSOnRestrictedPages = false; + /** @} */ # End of resource loader settings } /*************************************************************************//** diff --git a/includes/OutputPage.php b/includes/OutputPage.php index 3bb217560a..a51778853d 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -182,12 +182,14 @@ class OutputPage extends ContextSource { protected $mFeedLinksAppendQuery = null; - /** - * @var int - * The level of 'untrustworthiness' allowed for modules loaded on this page. + /** @var array + * What level of 'untrustworthiness' is allowed in CSS/JS modules loaded on this page? * @see ResourceLoaderModule::$origin + * ResourceLoaderModule::ORIGIN_ALL is assumed unless overridden; */ - protected $mAllowedModuleOrigin = ResourceLoaderModule::ORIGIN_ALL; + protected $mAllowedModules = array( + ResourceLoaderModule::TYPE_COMBINED => ResourceLoaderModule::ORIGIN_ALL, + ); /** @var bool Whether output is disabled. If this is true, the 'output' method will do nothing. */ protected $mDoNothing = false; @@ -1359,53 +1361,59 @@ class OutputPage extends ContextSource { } /** - * Restrict the page to loading modules bundled the software. + * Do not allow scripts which can be modified by wiki users to load on this page; + * only allow scripts bundled with, or generated by, the software. + * Site-wide styles are controlled by a config setting, since they can be + * used to create a custom skin/theme, but not user-specific ones. * - * Disallows the queue to contain any modules which can be modified by wiki - * users to load on this page. + * @todo this should be given a more accurate name */ public function disallowUserJs() { - $this->reduceAllowedModuleOrigin( ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL ); + $this->reduceAllowedModules( + ResourceLoaderModule::TYPE_SCRIPTS, + ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL + ); + + // Site-wide styles are controlled by a config setting, see bug 71621 + // for background on why. User styles are never allowed. + if ( $this->getConfig()->get( 'AllowSiteCSSOnRestrictedPages' ) ) { + $styleOrigin = ResourceLoaderModule::ORIGIN_USER_SITEWIDE; + } else { + $styleOrigin = ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL; + } + $this->reduceAllowedModules( + ResourceLoaderModule::TYPE_STYLES, + $styleOrigin + ); } /** - * Get the level of JavaScript / CSS untrustworthiness allowed on this page. - * + * Show what level of JavaScript / CSS untrustworthiness is allowed on this page * @see ResourceLoaderModule::$origin - * @param string $type Unused: Module origin allowance used to be fragmented by - * ResourceLoaderModule TYPE_ constants. + * @param string $type ResourceLoaderModule TYPE_ constant * @return int ResourceLoaderModule ORIGIN_ class constant */ - public function getAllowedModules( $type = null ) { - return $this->mAllowedModuleOrigin; + public function getAllowedModules( $type ) { + if ( $type == ResourceLoaderModule::TYPE_COMBINED ) { + return min( array_values( $this->mAllowedModules ) ); + } else { + return isset( $this->mAllowedModules[$type] ) + ? $this->mAllowedModules[$type] + : ResourceLoaderModule::ORIGIN_ALL; + } } /** * Set the highest level of CSS/JS untrustworthiness allowed * * @deprecated since 1.24 Raising level of allowed untrusted content is no longer supported. - * Use reduceAllowedModuleOrigin() instead. - * + * Use reduceAllowedModules() instead * @param string $type ResourceLoaderModule TYPE_ constant - * @param int $level ResourceLoaderModule ORIGIN_ constant + * @param int $level ResourceLoaderModule class constant */ public function setAllowedModules( $type, $level ) { wfDeprecated( __METHOD__, '1.24' ); - $this->reduceAllowedModuleOrigin( $level ); - } - - /** - * Limit the highest level of CSS/JS untrustworthiness allowed. - * - * @deprecated since 1.24 Module allowance is no longer fragmented by content type. - * Use reduceAllowedModuleOrigin() instead. - * - * @param string $type ResourceLoaderModule TYPE_ constant - * @param int $level ResourceLoaderModule ORIGIN_ class constant - */ - public function reduceAllowedModules( $type, $level ) { - wfDeprecated( __METHOD__, '1.24' ); - $this->reduceAllowedModuleOrigin( $level ); + $this->reduceAllowedModules( $type, $level ); } /** @@ -1414,10 +1422,11 @@ class OutputPage extends ContextSource { * If passed the same or a higher level than the current level of untrustworthiness set, the * level will remain unchanged. * + * @param string $type * @param int $level ResourceLoaderModule class constant */ - public function reduceAllowedModuleOrigin( $level ) { - $this->mAllowedModuleOrigin = min( $this->mAllowedModuleOrigin, $level ); + public function reduceAllowedModules( $type, $level ) { + $this->mAllowedModules[$type] = min( $this->getAllowedModules( $type ), $level ); } /**