From c72524dfa0b97c841b809786c85dfd71941b48c6 Mon Sep 17 00:00:00 2001 From: Kevin Israel Date: Fri, 26 Sep 2014 00:38:07 -0400 Subject: [PATCH] SECURITY: Add edit token to Special:ExpandTemplates On wikis that allow raw HTML, it is not safe to preview wikitext coming from an untrusted source such as a cross-site request. Thus add an edit token to the form, and when raw HTML is allowed, ensure the token is provided before showing the preview. Unfortunately, MediaWiki does not currently provide logged-out users with CSRF protection; in that case, do not show the preview unless anonymous editing is allowed (such wikis have been, and are still, vulnerable). Change-Id: I2f1caa57e8fc705ef52fc4b6f351a174b72b33cb --- includes/specials/SpecialExpandTemplates.php | 27 +++++++++++++++++++++++++++ languages/i18n/en.json | 2 ++ languages/i18n/qqq.json | 2 ++ 3 files changed, 31 insertions(+) diff --git a/includes/specials/SpecialExpandTemplates.php b/includes/specials/SpecialExpandTemplates.php index 269dff6..62f957f 100644 --- a/includes/specials/SpecialExpandTemplates.php +++ b/includes/specials/SpecialExpandTemplates.php @@ -139,6 +139,9 @@ class SpecialExpandTemplates extends SpecialPage { */ private function makeForm( $title, $input ) { $self = $this->getPageTitle(); + $request = $this->getRequest(); + $user = $this->getUser(); + $form = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $self->getLocalUrl() ) @@ -194,6 +197,7 @@ class SpecialExpandTemplates extends SpecialPage { array( 'accesskey' => 's' ) ) . '

'; $form .= "\n"; + $form .= Html::hidden( 'wpEditToken', $user->getEditToken( '', $request ) ); $form .= Xml::closeElement( 'form' ); return $form; @@ -244,6 +248,29 @@ class SpecialExpandTemplates extends SpecialPage { private function showHtmlPreview( Title $title, ParserOutput $pout, OutputPage $out ) { $lang = $title->getPageViewLanguage(); $out->addHTML( "

" . $this->msg( 'expand_templates_preview' )->escaped() . "

\n" ); + + if ( $this->getConfig()->get( 'RawHtml' ) ) { + $request = $this->getRequest(); + $user = $this->getUser(); + + // To prevent cross-site scripting attacks, don't show the preview if raw HTML is + // allowed and a valid edit token is not provided (bug 71111). However, MediaWiki + // does not currently provide logged-out users with CSRF protection; in that case, + // do not show the preview unless anonymous editing is allowed. + if ( $user->isAnon() && !$user->isAllowed( 'edit' ) ) { + $error = array( 'expand_templates_preview_fail_html_anon' ); + } elseif ( !$user->matchEditToken( $request->getVal( 'wpEditToken' ), '', $request ) ) { + $error = array( 'expand_templates_preview_fail_html' ); + } else { + $error = false; + } + + if ( $error ) { + $out->wrapWikiMsg( "
\n$1\n
", $error ); + return; + } + } + $out->addHTML( Html::openElement( 'div', array( 'class' => 'mw-content-' . $lang->getDir(), 'dir' => $lang->getDir(), diff --git a/languages/i18n/en.json b/languages/i18n/en.json index 12d1429..e9e1d1f 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -3527,6 +3527,8 @@ "expand_templates_generate_xml": "Show XML parse tree", "expand_templates_generate_rawhtml": "Show raw HTML", "expand_templates_preview": "Preview", + "expand_templates_preview_fail_html": "Because {{SITENAME}} has raw HTML enabled and there was a loss of session data, the preview is hidden as a precaution against JavaScript attacks.\n\nIf this is a legitimate preview attempt, please try again.\nIf it still does not work, try [[Special:UserLogout|logging out]] and logging back in.", + "expand_templates_preview_fail_html_anon": "Because {{SITENAME}} has raw HTML enabled and you are not logged in, the preview is hidden as a precaution against JavaScript attacks.\n\nIf this is a legitimate preview attempt, please [[Special:UserLogin|log in]] and try again.", "pagelanguage": "Page language selector", "pagelang-name": "Page", "pagelang-language": "Language", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index d480e2d..7d0f9ce 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -3689,6 +3689,8 @@ "expand_templates_generate_xml": "Used as checkbox label.", "expand_templates_generate_rawhtml": "Used as checkbox label.", "expand_templates_preview": "{{Identical|Preview}}", + "expand_templates_preview_fail_html": "Used as error message in Preview section of [[Special:ExpandTemplates]] page.", + "expand_templates_preview_fail_html_anon": "Used as error message in Preview section of [[Special:ExpandTemplates]] page.", "pagelanguage": "Title for page Special:PageLanguage", "pagelang-name": "Input label for page name on Special:PageLanguage\n{{Identical|Page}}", "pagelang-language": "Language selector label for Special:PageLanguage\n{{Identical|Language}}", -- 2.1.1