aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>2018-10-21 16:59:40 +0000
committerGerrit Code Review <gerrit@wikimedia.org>2018-10-21 16:59:40 +0000
commit90827e1f3a7f4991df5fe72edeb4eb63e3260c7c (patch)
tree287fc7e2f185a5625a5cfa1f6b2513a4ac1dabcc
parente0f4293088c9d82c2b8314e23db4bc3a3e6fdfda (diff)
parentc2e7d13240715ef5512510419727ca4bfd1c0fea (diff)
downloadmediawikicore-90827e1f3a7f4991df5fe72edeb4eb63e3260c7c.tar.gz
mediawikicore-90827e1f3a7f4991df5fe72edeb4eb63e3260c7c.zip
Merge "SECURITY: Don't allow loading unprotected JS files" into REL1_32
-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"
}