From a5e349c90843353df5e3c961ac78533bf0644897 Mon Sep 17 00:00:00 2001 From: Brian Wolff Date: Thu, 27 Sep 2018 11:42:37 +0000 Subject: [PATCH] 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 --- RELEASE-NOTES-1.31 | 2 ++ includes/actions/RawAction.php | 24 ++++++++++++++++++++++++ languages/i18n/en.json | 3 ++- languages/i18n/qqq.json | 3 ++- 4 files changed, 30 insertions(+), 2 deletions(-) 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" } -- 2.20.1