X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2Factions%2FRawAction.php;h=3fda401bd764f2727cedbf07b17dc05b23570284;hp=812f9623ff99db64a5a70fe46533c290bc9d2acd;hb=a5e349c90843353df5e3c961ac78533bf0644897;hpb=8c371e76b7c10a00acac185ef91ef2627e0d582d diff --git a/includes/actions/RawAction.php b/includes/actions/RawAction.php index 812f9623ff..3fda401bd7 100644 --- a/includes/actions/RawAction.php +++ b/includes/actions/RawAction.php @@ -26,6 +26,8 @@ * @file */ +use MediaWiki\Logger\LoggerFactory; + /** * A simple method to retrieve the plain source of an article, * using "action=raw" in the GET request string. @@ -85,7 +87,6 @@ class RawAction extends FormlessAction { $response->header( $this->getOutput()->getKeyHeader() ); } - $response->header( 'Content-type: ' . $contentType . '; charset=UTF-8' ); // Output may contain user-specific data; // vary generated content for open sessions on private wikis $privateCache = !User::isEveryoneAllowed( 'read' ) && @@ -97,6 +98,57 @@ class RawAction extends FormlessAction { 'Cache-Control: ' . $mode . ', s-maxage=' . $smaxage . ', max-age=' . $maxage ); + // In the event of user JS, don't allow loading a user JS/CSS/Json + // subpage that has no registered user associated with, as + // someone could register the account and take control of the + // JS/CSS/Json page. + $title = $this->getTitle(); + if ( $title->isUserConfigPage() && $contentType !== 'text/x-wiki' ) { + // not using getRootText() as we want this to work + // even if subpages are disabled. + $rootPage = strtok( $title->getText(), '/' ); + $userFromTitle = User::newFromName( $rootPage, 'usable' ); + if ( !$userFromTitle || $userFromTitle->getId() === 0 ) { + $log = LoggerFactory::getInstance( "security" ); + $log->warning( + "Unsafe JS/CSS/Json load - {user} loaded {title} with {ctype}", + [ + 'user' => $this->getUser()->getName(), + 'title' => $title->getPrefixedDBKey(), + 'ctype' => $contentType, + ] + ); + $msg = wfMessage( 'unregistered-user-config' ); + throw new HttpError( 403, $msg ); + } + } + + // Don't allow loading non-protected pages as javascript. + // In future we may further restrict this to only CONTENT_MODEL_JAVASCRIPT + // in NS_MEDIAWIKI or NS_USER, as well as including other config types, + // but for now be more permissive. Allowing protected pages outside of + // NS_USER and NS_MEDIAWIKI in particular should be considered a temporary + // allowance. + if ( + $contentType === 'text/javascript' && + !$title->isUserJsConfigPage() && + !$title->inNamespace( NS_MEDIAWIKI ) && + !in_array( 'sysop', $title->getRestrictions( 'edit' ) ) && + !in_array( 'editprotected', $title->getRestrictions( 'edit' ) ) + ) { + + $log = LoggerFactory::getInstance( "security" ); + $log->info( "Blocked loading unprotected JS {title} for {user}", + [ + 'user' => $this->getUser()->getName(), + 'title' => $title->getPrefixedDBKey(), + ] + ); + throw new HttpError( 403, wfMessage( 'unprotected-js' ) ); + } + + $response->header( 'Content-type: ' . $contentType . '; charset=UTF-8' ); + $text = $this->getRawText(); // Don't return a 404 response for CSS or JavaScript;