diff options
Diffstat (limited to 'includes')
-rw-r--r-- | includes/DefaultSettings.php | 9 | ||||
-rw-r--r-- | includes/OutputPage.php | 11 | ||||
-rw-r--r-- | includes/api/ApiMain.php | 2 | ||||
-rw-r--r-- | includes/resourceloader/ResourceLoader.php | 51 | ||||
-rw-r--r-- | includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php | 29 | ||||
-rw-r--r-- | includes/resourceloader/ResourceLoaderUserOptionsModule.php | 30 | ||||
-rw-r--r-- | includes/specials/SpecialUpload.php | 9 |
7 files changed, 42 insertions, 99 deletions
diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index d75496b24a37..93d2b81cfb15 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -33,7 +33,7 @@ $wgConf = new SiteConfiguration; /** @endcond */ /** MediaWiki version number */ -$wgVersion = '1.19.0beta1'; +$wgVersion = '1.19.0beta2'; /** Name of the site. It must be changed in LocalSettings.php */ $wgSitename = 'MediaWiki'; @@ -2580,13 +2580,6 @@ $wgResourceLoaderMaxage = array( ); /** - * Whether to embed private modules inline with HTML output or to bypass - * caching and check the user parameter against $wgUser to prevent - * unauthorized access to private modules. - */ -$wgResourceLoaderInlinePrivateModules = true; - -/** * The default debug mode (on/off) for of ResourceLoader requests. This will still * be overridden when the debug URL parameter is used. */ diff --git a/includes/OutputPage.php b/includes/OutputPage.php index 003aee7cf437..a91d54657a64 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -2505,7 +2505,7 @@ $templates * @return string html <script> and <style> tags */ protected function makeResourceLoaderLink( $modules, $only, $useESI = false, array $extraQuery = array(), $loadCall = false ) { - global $wgResourceLoaderUseESI, $wgResourceLoaderInlinePrivateModules; + global $wgResourceLoaderUseESI; if ( !count( $modules ) ) { return ''; @@ -2584,10 +2584,11 @@ $templates continue; } - // Support inlining of private modules if configured as such. Note that these - // modules should be loaded from getHeadScripts() before the first loader call. - // Otherwise other modules can't properly use them as dependencies (bug 30914) - if ( $group === 'private' && $wgResourceLoaderInlinePrivateModules ) { + // Inline private modules. These can't be loaded through load.php for security + // reasons, see bug 34907. Note that these modules should be loaded from + // getHeadScripts() before the first loader call. Otherwise other modules can't + // properly use them as dependencies (bug 30914) + if ( $group === 'private' ) { if ( $only == ResourceLoaderModule::TYPE_STYLES ) { $links .= Html::inlineStyle( $resourceLoader->makeModuleResponse( $context, $modules ) diff --git a/includes/api/ApiMain.php b/includes/api/ApiMain.php index 5fedf8df0561..761f0fe3a665 100644 --- a/includes/api/ApiMain.php +++ b/includes/api/ApiMain.php @@ -595,7 +595,7 @@ class ApiMain extends ApiBase { // Die if token required, but not provided (unless there is a gettoken parameter) $salt = $module->getTokenSalt(); - if ( $salt !== false && !isset( $moduleParams['gettoken'] ) ) { + if ( $salt !== false && !$moduleParams['gettoken'] ) { if ( !isset( $moduleParams['token'] ) ) { $this->dieUsageMsg( array( 'missingparam', 'token' ) ); } else { diff --git a/includes/resourceloader/ResourceLoader.php b/includes/resourceloader/ResourceLoader.php index 55fbddc401b2..9175b10de27b 100644 --- a/includes/resourceloader/ResourceLoader.php +++ b/includes/resourceloader/ResourceLoader.php @@ -173,7 +173,7 @@ class ResourceLoader { $cache->set( $key, $result ); } catch ( Exception $exception ) { // Return exception as a comment - $result = "/*\n{$exception->__toString()}\n*/\n"; + $result = $this->makeComment( $exception->__toString() ); } wfProfileOut( __METHOD__ ); @@ -430,13 +430,20 @@ class ResourceLoader { ob_start(); wfProfileIn( __METHOD__ ); - $exceptions = ''; + $errors = ''; // Split requested modules into two groups, modules and missing $modules = array(); $missing = array(); foreach ( $context->getModules() as $name ) { if ( isset( $this->moduleInfos[$name] ) ) { + $module = $this->getModule( $name ); + // Do not allow private modules to be loaded from the web. + // This is a security issue, see bug 34907. + if ( $module->getGroup() === 'private' ) { + $errors .= $this->makeComment( "Cannot show private module \"$name\"" ); + continue; + } $modules[$name] = $this->getModule( $name ); } else { $missing[] = $name; @@ -448,12 +455,11 @@ class ResourceLoader { $this->preloadModuleInfo( array_keys( $modules ), $context ); } catch( Exception $e ) { // Add exception to the output as a comment - $exceptions .= "/*\n{$e->__toString()}\n*/\n"; + $errors .= $this->makeComment( $e->__toString() ); } wfProfileIn( __METHOD__.'-getModifiedTime' ); - $private = false; // To send Last-Modified and support If-Modified-Since, we need to detect // the last modified time $mtime = wfTimestamp( TS_UNIX, $wgCacheEpoch ); @@ -462,22 +468,18 @@ class ResourceLoader { * @var $module ResourceLoaderModule */ try { - // Bypass Squid and other shared caches if the request includes any private modules - if ( $module->getGroup() === 'private' ) { - $private = true; - } // Calculate maximum modified time $mtime = max( $mtime, $module->getModifiedTime( $context ) ); } catch ( Exception $e ) { // Add exception to the output as a comment - $exceptions .= "/*\n{$e->__toString()}\n*/\n"; + $errors .= $this->makeComment( $e->__toString() ); } } wfProfileOut( __METHOD__.'-getModifiedTime' ); // Send content type and cache related headers - $this->sendResponseHeaders( $context, $mtime, $private ); + $this->sendResponseHeaders( $context, $mtime ); // If there's an If-Modified-Since header, respond with a 304 appropriately if ( $this->tryRespondLastModified( $context, $mtime ) ) { @@ -489,20 +491,20 @@ class ResourceLoader { $response = $this->makeModuleResponse( $context, $modules, $missing ); // Prepend comments indicating exceptions - $response = $exceptions . $response; + $response = $errors . $response; // Capture any PHP warnings from the output buffer and append them to the // response in a comment if we're in debug mode. if ( $context->getDebug() && strlen( $warnings = ob_get_contents() ) ) { - $response = "/*\n$warnings\n*/\n" . $response; + $response = $this->makeComment( $warnings ) . $response; } // Remove the output buffer and output the response ob_end_clean(); echo $response; - // Save response to file cache unless there are private modules or errors - if ( isset( $fileCache ) && !$private && !$exceptions && !$missing ) { + // Save response to file cache unless there are errors + if ( isset( $fileCache ) && !$errors && !$missing ) { // Cache single modules...and other requests if there are enough hits if ( ResourceFileCache::useFileCache( $context ) ) { if ( $fileCache->isCacheWorthy() ) { @@ -520,10 +522,9 @@ class ResourceLoader { * Send content type and last modified headers to the client. * @param $context ResourceLoaderContext * @param $mtime string TS_MW timestamp to use for last-modified - * @param $private bool True iff response contains any private modules * @return void */ - protected function sendResponseHeaders( ResourceLoaderContext $context, $mtime, $private ) { + protected function sendResponseHeaders( ResourceLoaderContext $context, $mtime ) { global $wgResourceLoaderMaxage; // If a version wasn't specified we need a shorter expiry time for updates // to propagate to clients quickly @@ -547,13 +548,8 @@ class ResourceLoader { header( 'Cache-Control: private, no-cache, must-revalidate' ); header( 'Pragma: no-cache' ); } else { - if ( $private ) { - header( "Cache-Control: private, max-age=$maxage" ); - $exp = $maxage; - } else { - header( "Cache-Control: public, max-age=$maxage, s-maxage=$smaxage" ); - $exp = min( $maxage, $smaxage ); - } + header( "Cache-Control: public, max-age=$maxage, s-maxage=$smaxage" ); + $exp = min( $maxage, $smaxage ); header( 'Expires: ' . wfTimestamp( TS_RFC2822, $exp + time() ) ); } } @@ -650,6 +646,11 @@ class ResourceLoader { return false; // cache miss } + protected function makeComment( $text ) { + $encText = str_replace( '*/', '* /', $text ); + return "/*\n$encText\n*/\n"; + } + /** * Generates code for a response * @@ -674,7 +675,7 @@ class ResourceLoader { $blobs = MessageBlobStore::get( $this, $modules, $context->getLanguage() ); } catch ( Exception $e ) { // Add exception to the output as a comment - $exceptions .= "/*\n{$e->__toString()}\n*/\n"; + $exceptions .= $this->makeComment( $e->__toString() ); } } else { $blobs = array(); @@ -753,7 +754,7 @@ class ResourceLoader { } } catch ( Exception $e ) { // Add exception to the output as a comment - $exceptions .= "/*\n{$e->__toString()}\n*/\n"; + $exceptions .= $this->makeComment( $e->__toString() ); // Register module as missing $missing[] = $name; diff --git a/includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php b/includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php index b5a24354e019..02693d3ec9b3 100644 --- a/includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php +++ b/includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php @@ -44,30 +44,7 @@ class ResourceLoaderUserCSSPrefsModule extends ResourceLoaderModule { } global $wgUser; - - if ( $context->getUser() === $wgUser->getName() ) { - return $this->modifiedTime[$hash] = wfTimestamp( TS_UNIX, $wgUser->getTouched() ); - } else { - return 1; - } - } - - /** - * Fetch the context's user options, or if it doesn't match current user, - * the default options. - * - * @param $context ResourceLoaderContext: Context object - * @return Array: List of user options keyed by option name - */ - protected function contextUserOptions( ResourceLoaderContext $context ) { - global $wgUser; - - // Verify identity -- this is a private module - if ( $context->getUser() === $wgUser->getName() ) { - return $wgUser->getOptions(); - } else { - return User::getDefaultOptions(); - } + return $this->modifiedTime[$hash] = wfTimestamp( TS_UNIX, $wgUser->getTouched() ); } /** @@ -75,10 +52,10 @@ class ResourceLoaderUserCSSPrefsModule extends ResourceLoaderModule { * @return array */ public function getStyles( ResourceLoaderContext $context ) { - global $wgAllowUserCssPrefs; + global $wgAllowUserCssPrefs, $wgUser; if ( $wgAllowUserCssPrefs ) { - $options = $this->contextUserOptions( $context ); + $options = $wgUser->getOptions(); // Build CSS rules $rules = array(); diff --git a/includes/resourceloader/ResourceLoaderUserOptionsModule.php b/includes/resourceloader/ResourceLoaderUserOptionsModule.php index 84932adddf8c..7b1622053563 100644 --- a/includes/resourceloader/ResourceLoaderUserOptionsModule.php +++ b/includes/resourceloader/ResourceLoaderUserOptionsModule.php @@ -42,32 +42,9 @@ class ResourceLoaderUserOptionsModule extends ResourceLoaderModule { if ( isset( $this->modifiedTime[$hash] ) ) { return $this->modifiedTime[$hash]; } - + global $wgUser; - - if ( $context->getUser() === $wgUser->getName() ) { - return $this->modifiedTime[$hash] = wfTimestamp( TS_UNIX, $wgUser->getTouched() ); - } else { - return 1; - } - } - - /** - * Fetch the context's user options, or if it doesn't match current user, - * the default options. - * - * @param $context ResourceLoaderContext: Context object - * @return Array: List of user options keyed by option name - */ - protected function contextUserOptions( ResourceLoaderContext $context ) { - global $wgUser; - - // Verify identity -- this is a private module - if ( $context->getUser() === $wgUser->getName() ) { - return $wgUser->getOptions(); - } else { - return User::getDefaultOptions(); - } + return $this->modifiedTime[$hash] = wfTimestamp( TS_UNIX, $wgUser->getTouched() ); } /** @@ -75,8 +52,9 @@ class ResourceLoaderUserOptionsModule extends ResourceLoaderModule { * @return string */ public function getScript( ResourceLoaderContext $context ) { + global $wgUser; return Xml::encodeJsCall( 'mw.user.options.set', - array( $this->contextUserOptions( $context ) ) ); + array( $wgUser->getOptions() ) ); } /** diff --git a/includes/specials/SpecialUpload.php b/includes/specials/SpecialUpload.php index 3711a6ac15db..d6a76d02bd4b 100644 --- a/includes/specials/SpecialUpload.php +++ b/includes/specials/SpecialUpload.php @@ -111,14 +111,7 @@ class SpecialUpload extends SpecialPage { // If it was posted check for the token (no remote POST'ing with user credentials) $token = $request->getVal( 'wpEditToken' ); - if( $this->mSourceType == 'file' && $token == null ) { - // Skip token check for file uploads as that can't be faked via JS... - // Some client-side tools don't expect to need to send wpEditToken - // with their submissions, as that's new in 1.16. - $this->mTokenOk = true; - } else { - $this->mTokenOk = $this->getUser()->matchEditToken( $token ); - } + $this->mTokenOk = $this->getUser()->matchEditToken( $token ); $this->uploadFormTextTop = ''; $this->uploadFormTextAfterSummary = ''; |