SECURITY: Copy prevent-clickjacking between OutputPage and ParserOutput
authorBrad Jorsch <bjorsch@wikimedia.org>
Thu, 10 Jul 2014 19:16:29 +0000 (12:16 -0700)
committermglaser <glaser@hallowelt.biz>
Wed, 30 Jul 2014 18:26:58 +0000 (20:26 +0200)
Special page transclusion returns an OutputPage, whose metadata is
copied into the ParserOutput, and then later back into an OutputPage.
The "preventClickjacking" flag should be part of that metadata.

Bug: 65778
Change-Id: I17d2720fb94bb383a92059e5adbf6c16ee3e9ef4

includes/OutputPage.php
includes/parser/ParserOutput.php

index 566ee87..a64d049 100644 (file)
@@ -1641,6 +1641,8 @@ class OutputPage extends ContextSource {
                $this->addModuleStyles( $parserOutput->getModuleStyles() );
                $this->addModuleMessages( $parserOutput->getModuleMessages() );
                $this->addJsConfigVars( $parserOutput->getJsConfigVars() );
+               $this->mPreventClickjacking = $this->mPreventClickjacking
+                       || $parserOutput->preventClickjacking();
 
                // Template versioning...
                foreach ( (array)$parserOutput->getTemplateIds() as $ns => $dbks ) {
@@ -1968,6 +1970,16 @@ class OutputPage extends ContextSource {
                $this->mPreventClickjacking = false;
        }
 
+       /**
+        * Get the prevent-clickjacking flag
+        *
+        * @since 1.24
+        * @return boolean
+        */
+       public function getPreventClickjacking() {
+               return $this->mPreventClickjacking;
+       }
+
        /**
         * Get the X-Frame-Options header value (without the name part), or false
         * if there isn't one. This is used by Skin to determine whether to enable
index f6ad931..3de7505 100644 (file)
@@ -56,6 +56,7 @@ class ParserOutput extends CacheTime {
                private $mExtensionData = array(); # extra data used by extensions
                private $mLimitReportData = array(); # Parser limit report data
                private $mParseStartTime = array(); # Timestamps for getTimeSinceStart()
+               private $mPreventClickjacking = false; # Whether to emit X-Frame-Options: DENY
 
        const EDITSECTION_REGEX =
                '#<(?:mw:)?editsection page="(.*?)" section="(.*?)"(?:/>|>(.*?)(</(?:mw:)?editsection>))#';
@@ -471,6 +472,7 @@ class ParserOutput extends CacheTime {
                $this->addJsConfigVars( $out->getJsConfigVars() );
 
                $this->mHeadItems = array_merge( $this->mHeadItems, $out->getHeadItemsArray() );
+               $this->mPreventClickjacking = $this->mPreventClickjacking || $out->getPreventClickjacking();
        }
 
        /**
@@ -793,6 +795,17 @@ class ParserOutput extends CacheTime {
                $this->mLimitReportData[$key] = $value;
        }
 
+       /**
+        * Get or set the prevent-clickjacking flag
+        *
+        * @since 1.24
+        * @param boolean|null $flag New flag value, or null to leave it unchanged
+        * @return boolean Old flag value
+        */
+       public function preventClickjacking( $flag = null ) {
+               return wfSetVar( $this->mPreventClickjacking, $flag );
+       }
+
        /**
         * Save space for for serialization by removing useless values
         */