Yaron Koren has submitted this change and it was merged.
Change subject: Fix possibility for arbitrary HTML output
......................................................................
Fix possibility for arbitrary HTML output
Trusting the page content is inherently insecure. Instead, store the
parsed content in an array and output an index to retrieve it later.
Modernize code style slightly, while at it.
Bug: T88964
Change-Id: I00ede9c7f333f32f2cc7722781b06f97a544927f
---
M WidgetRenderer.php
M Widgets.php
2 files changed, 23 insertions(+), 22 deletions(-)
Approvals:
Yaron Koren: Checked; Looks good to me, approved
jenkins-bot: Verified
diff --git a/WidgetRenderer.php b/WidgetRenderer.php
index 3ef961a..9682b59 100644
--- a/WidgetRenderer.php
+++ b/WidgetRenderer.php
@@ -4,15 +4,16 @@
*/
class WidgetRenderer {
-
- // A randomly-generated string, used to prevent malicious users from
- // spoofing the output of #widget in order to have arbitrary
- // JavaScript show up in the page's output.
- static $mRandomString;
-
+ // The prefix and suffix for the widget strip marker.
+ private static $markerPrefix = "START_WIDGET";
+ private static $markerSuffix = "END_WIDGET";
+
+ // Stores the compiled widgets for after the parser has run.
+ private static $widgets = array();
+
public static function initRandomString() {
- // Set the random string, used in both encoding and decoding.
- self::$mRandomString = substr( base64_encode( rand() ), 0, 7 );
+ // Add a random string to the prefix to ensure no conflicts
with normal content.
+ self::$markerPrefix .= wfRandomString( 16 );
}
public static function renderWidget( &$parser, $widgetName ) {
@@ -127,20 +128,20 @@
try {
$output = $smarty->fetch( "wiki:$widgetName" );
} catch ( Exception $e ) {
- return '<div class=\"error\">' . wfMessage(
'widgets-error', htmlentities( $widgetName ) )->text() . '</div>';
+ return '<strong class="error">' . wfMessage(
'widgets-error', htmlentities( $widgetName ) )->text() . '</strong>';
}
-
- // Hide the widget from the parser.
- $output = 'ENCODED_CONTENT ' . self::$mRandomString .
base64_encode($output) . ' END_ENCODED_CONTENT';
- return array( $output, 'noparse' => true, 'isHTML' => true );
+
+ // To prevent the widget output from being tampered with, the
compiled HTML
+ // is stored and a strip marker with an index to retrieve it
later is returned.
+ $index = array_push( self::$widgets, $output ) - 1;
+ return self::$markerPrefix . '-' . $index . self::$markerSuffix;
}
- public static function processEncodedWidgetOutput( &$out, &$text ) {
- // Find all hidden content and restore to normal
+ public static function outputCompiledWidget( &$out, &$text ) {
$text = preg_replace_callback(
- '/ENCODED_CONTENT ' . self::$mRandomString .
'([0-9a-zA-Z\/+]+=*)* END_ENCODED_CONTENT/',
+ '/' . self::$markerPrefix . '-(\d+)' .
self::$markerSuffix . '/S',
function( $matches ) {
- return base64_decode( $matches[1]);
+ return self::$widgets[$matches[1]];
},
$text
);
diff --git a/Widgets.php b/Widgets.php
index 6c52c5a..887ca43 100644
--- a/Widgets.php
+++ b/Widgets.php
@@ -17,7 +17,7 @@
'name' => 'Widgets',
'descriptionmsg' => 'widgets-desc',
'version' => '1.1',
- 'author' => '[http://www.sergeychernyshev.com Sergey Chernyshev]',
+ 'author' => array( '[http://www.sergeychernyshev.com Sergey
Chernyshev]', '...' ),
'url' => 'https://www.mediawiki.org/wiki/Extension:Widgets'
);
@@ -50,11 +50,11 @@
// Set a default directory for storage of compiled templates
$wgWidgetsCompileDir = "$IP/extensions/Widgets/compiled_templates/";
-$dir = dirname( __FILE__ ) . '/';
+$dir = __DIR__ . '/';
// Initialize Smarty
require_once( $dir . 'smarty/libs/Smarty.class.php' );
-$wgMessagesDirs['Widgets'] = __DIR__ . '/i18n';
+$wgMessagesDirs['Widgets'] = $dir . 'i18n';
$wgExtensionMessagesFiles['Widgets'] = $dir . 'Widgets.i18n.php';
$wgExtensionMessagesFiles['WidgetsNamespaces'] = $dir .
'Widgets.i18n.namespaces.php';
$wgAutoloadClasses['WidgetRenderer'] = $dir . 'WidgetRenderer.php';
@@ -65,7 +65,7 @@
$wgExtensionFunctions[] = 'widgetNamespacesInit';
$wgExtensionFunctions[] = 'WidgetRenderer::initRandomString';
$wgHooks['ParserFirstCallInit'][] = 'widgetParserFunctions';
-$wgHooks['ParserAfterTidy'][] = 'WidgetRenderer::processEncodedWidgetOutput';
+$wgHooks['ParserAfterTidy'][] = 'WidgetRenderer::outputCompiledWidget';
$wgHooks['CanonicalNamespaces'][] = 'widgetsAddNamespaces';
/**
@@ -73,7 +73,7 @@
* @return bool
*/
function widgetParserFunctions( &$parser ) {
- $parser->setFunctionHook( 'widget', array( 'WidgetRenderer',
'renderWidget' ) );
+ $parser->setFunctionHook( 'widget', 'WidgetRenderer::renderWidget' );
return true;
}
--
To view, visit https://gerrit.wikimedia.org/r/189449
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I00ede9c7f333f32f2cc7722781b06f97a544927f
Gerrit-PatchSet: 2
Gerrit-Project: mediawiki/extensions/Widgets
Gerrit-Branch: master
Gerrit-Owner: Majr <[email protected]>
Gerrit-Reviewer: Majr <[email protected]>
Gerrit-Reviewer: Yaron Koren <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
Gerrit-Reviewer: shinjiman <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits