From: Brian Wolff Date: Thu, 27 Sep 2018 11:42:37 +0000 (+0000) Subject: SECURITY: Don't allow loading unprotected JS files X-Git-Tag: 1.31.2~75 X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=commitdiff_plain;h=a5e349c90843353df5e3c961ac78533bf0644897;hp=90232b6f36ee5a1473f2e865cc7a72d0014db4c7 SECURITY: Don't allow loading unprotected JS files This is meant to protect against malicious people while avoiding annoying good users as much as possible. We may want to restrict this further in the future, but that's something that can be discussed in the normal way. Bug: T194204 Bug: T113042 Bug: T112937 Change-Id: I27e049bae78b5c0f63b10f454b740cb1dc394813 --- diff --git a/RELEASE-NOTES-1.31 b/RELEASE-NOTES-1.31 index 3e7f5d1534..6421a043c4 100644 --- a/RELEASE-NOTES-1.31 +++ b/RELEASE-NOTES-1.31 @@ -18,6 +18,8 @@ THIS IS NOT A RELEASE YET * (T207541) Pass email address to mail(). * (T207603) User JS may no longer be loaded with mime type text/javascript if there is no account associated with the username. +* (T113042) Do not allow loading pages raw with a text/javascript MIME type if + non-admins can edit the page. == MediaWiki 1.31.1 == diff --git a/includes/actions/RawAction.php b/includes/actions/RawAction.php index 159e7081a4..3fda401bd7 100644 --- a/includes/actions/RawAction.php +++ b/includes/actions/RawAction.php @@ -123,6 +123,30 @@ class RawAction extends FormlessAction { } } + // 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(); diff --git a/languages/i18n/en.json b/languages/i18n/en.json index 89564e05a0..31adb7b947 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -4468,5 +4468,6 @@ "pagedata-text": "This page provides a data interface to pages. Please provide the page title in the URL, using subpage syntax.\n* Content negotiation applies based on your client's Accept header. This means that the page data will be provided in the format preferred by your client.", "pagedata-not-acceptable": "No matching format found. Supported MIME types: $1", "pagedata-bad-title": "Invalid title: $1.", - "unregistered-user-config": "For security reasons JavaScript, CSS and JSON user subpages cannot be loaded for unregistered users." + "unregistered-user-config": "For security reasons JavaScript, CSS and JSON user subpages cannot be loaded for unregistered users.", + "unprotected-js": "For security reasons JavaScript cannot be loaded from unprotected pages. Please only create javascript in the MediaWiki: namespace or as a User subpage" } diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index 8e8372bb75..6348926e8e 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -4665,5 +4665,6 @@ "pagedata-text": "Error shown when none of the formats acceptable to the client is supported (HTTP error 406). Parameters:\n* $1 - the list of supported MIME types", "pagedata-not-acceptable": "No matching format found. Supported MIME types: $1", "pagedata-bad-title": "Error shown when the requested title is invalid. Parameters:\n* $1: the malformed ID", - "unregistered-user-config": "Shown when viewing a user JS, CSS or JSON subpage with ?action=raw&ctype= where there is no such user. It is shown as a paragraph after a header saying 'Forbidden'." + "unregistered-user-config": "Shown when viewing a user JS, CSS or JSON subpage with ?action=raw&ctype= where there is no such user. It is shown as a paragraph after a header saying 'Forbidden'.", + "unprotected-js": "Error message shown when trying to load javascript via action=raw that is not protected" }