SECURITY: OutputPage: Remove separation of css and js module allowance
authorTimo Tijhof <krinklemail@gmail.com>
Thu, 11 Sep 2014 23:14:16 +0000 (18:14 -0500)
committermglaser <glaser@hallowelt.biz>
Wed, 1 Oct 2014 20:48:29 +0000 (22:48 +0200)
* No longer segment module origin allowance by an "only=" content
type. Both can be sensitive security-wise and there's no valid
use case for allowing CSS anywhere you want to disallow JS. Both
can significantly impact the user interface and cause unintended
actions to be taken on the user's behalf, or desired actions to
be made practically impossible.

* While at it, also remove the ability to set the module allowance
directly. The reduceAllowedModuleOrigin method is all we need.
I couldn't find usage or mention of setAllowedModules() in
mediawiki-core nor in any other Wikimedia-hosted repository.

Bug: 70672
Change-Id: I308e794daca27a9380c67be350f8ab51f9c2de34

includes/OutputPage.php

index e1b6e0e..e9fec18 100644 (file)
@@ -179,14 +179,12 @@ class OutputPage extends ContextSource {
 
        protected $mFeedLinksAppendQuery = null;
 
-       /** @var array
-        * What level of 'untrustworthiness' is allowed in CSS/JS modules loaded on this page?
+       /**
+        * @var int
+        * The level of 'untrustworthiness' allowed for modules loaded on this page.
         * @see ResourceLoaderModule::$origin
-        * ResourceLoaderModule::ORIGIN_ALL is assumed unless overridden;
         */
-       protected $mAllowedModules = array(
-               ResourceLoaderModule::TYPE_COMBINED => ResourceLoaderModule::ORIGIN_ALL,
-       );
+       protected $mAllowedModuleOrigin = ResourceLoaderModule::ORIGIN_ALL;
 
        /** @var bool Whether output is disabled.  If this is true, the 'output' method will do nothing. */
        protected $mDoNothing = false;
@@ -1332,48 +1330,65 @@ class OutputPage extends ContextSource {
        }
 
        /**
-        * 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.
+        * Restrict the page to loading modules bundled the software.
+        *
+        * Disallows the queue to contain any modules which can be modified by wiki
+        * users to load on this page.
         */
        public function disallowUserJs() {
-               $this->reduceAllowedModules(
-                       ResourceLoaderModule::TYPE_SCRIPTS,
-                       ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL
-               );
+               $this->reduceAllowedModuleOrigin( ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL );
        }
 
        /**
-        * Show what level of JavaScript / CSS untrustworthiness is allowed on this page
+        * Get the level of JavaScript / CSS untrustworthiness allowed on this page.
+        *
         * @see ResourceLoaderModule::$origin
-        * @param string $type ResourceLoaderModule TYPE_ constant
+        * @param string $type Unused: Module origin allowance used to be fragmented by
+        *  ResourceLoaderModule TYPE_ constants.
         * @return int ResourceLoaderModule ORIGIN_ class constant
         */
-       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;
-               }
+       public function getAllowedModules( $type = null ) {
+               return $this->mAllowedModuleOrigin;
        }
 
        /**
         * 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.
+        *
         * @param string $type ResourceLoaderModule TYPE_ constant
-        * @param int $level ResourceLoaderModule class constant
+        * @param int $level ResourceLoaderModule ORIGIN_ constant
         */
        public function setAllowedModules( $type, $level ) {
-               $this->mAllowedModules[$type] = $level;
+               wfDeprecated( __METHOD__, '1.24' );
+               $this->reduceAllowedModuleOrigin( $level );
        }
 
        /**
-        * As for setAllowedModules(), but don't inadvertently make the page more accessible
-        * @param string $type
-        * @param int $level ResourceLoaderModule class constant
+        * 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 ) {
-               $this->mAllowedModules[$type] = min( $this->getAllowedModules( $type ), $level );
+               wfDeprecated( __METHOD__, '1.24' );
+               $this->reduceAllowedModuleOrigin( $level );
+       }
+
+       /**
+        * Limit the highest level of CSS/JS untrustworthiness allowed.
+        *
+        * If passed the same or a higher level than the current level of untrustworthiness set, the
+        * level will remain unchanged.
+        *
+        * @param int $level ResourceLoaderModule class constant
+        */
+       public function reduceAllowedModuleOrigin( $level ) {
+               $this->mAllowedModuleOrigin = min( $this->mAllowedModuleOrigin, $level );
        }
 
        /**