aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Wolff <bawolff+wn@gmail.com>2018-09-27 11:42:37 +0000
committerBrian Wolff <bawolff+wn@gmail.com>2018-10-21 16:09:40 +0000
commitc2e7d13240715ef5512510419727ca4bfd1c0fea (patch)
treefe7052666a6ce7b5fcdfac67b61826b360283e2a
parent8126f1e35bd773f0f72bccc6939ecc89bb83987d (diff)
downloadmediawikicore-c2e7d13240715ef5512510419727ca4bfd1c0fea.tar.gz
mediawikicore-c2e7d13240715ef5512510419727ca4bfd1c0fea.zip
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
-rw-r--r--includes/actions/RawAction.php24
-rw-r--r--languages/i18n/en.json3
-rw-r--r--languages/i18n/qqq.json3
3 files changed, 28 insertions, 2 deletions
diff --git a/includes/actions/RawAction.php b/includes/actions/RawAction.php
index b5a6d3ac2598..77a8b14e2c2c 100644
--- a/includes/actions/RawAction.php
+++ b/includes/actions/RawAction.php
@@ -129,6 +129,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 ea6305423b61..bca9f471acfe 100644
--- a/languages/i18n/en.json
+++ b/languages/i18n/en.json
@@ -4519,5 +4519,6 @@
"passwordpolicies-policy-passwordcannotmatchblacklist": "Password cannot match specifically blacklisted passwords",
"passwordpolicies-policy-maximalpasswordlength": "Password must be less than $1 {{PLURAL:$1|character|characters}} long",
"passwordpolicies-policy-passwordcannotbepopular": "Password cannot be {{PLURAL:$1|the popular password|in the list of $1 popular passwords}}",
- "easydeflate-invaliddeflate": "Content provided is not properly deflated"
+ "easydeflate-invaliddeflate": "Content provided is not properly deflated",
+ "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 a17cfca049dc..cbee32b04654 100644
--- a/languages/i18n/qqq.json
+++ b/languages/i18n/qqq.json
@@ -4721,5 +4721,6 @@
"passwordpolicies-policy-passwordcannotmatchblacklist": "Password policy that enforces that passwords are not on a list of blacklisted passwords (often previously used during MediaWiki automated testing)",
"passwordpolicies-policy-maximalpasswordlength": "Password policy that enforces a maximum number of characters a password must be. $1 - maximum number of characters that a password can be",
"passwordpolicies-policy-passwordcannotbepopular": "Password policy that enforces that a password is not in a list of $1 number of \"popular\" passwords. $1 - number of popular passwords the password will be checked against",
- "easydeflate-invaliddeflate": "Error message if the content passed to easydeflate was not deflated (compressed) properly"
+ "easydeflate-invaliddeflate": "Error message if the content passed to easydeflate was not deflated (compressed) properly",
+ "unprotected-js": "Error message shown when trying to load javascript via action=raw that is not protected"
}