Majr has uploaded a new change for review.
https://gerrit.wikimedia.org/r/189449
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.
Bug: T88964
Change-Id: I00ede9c7f333f32f2cc7722781b06f97a544927f
---
M WidgetRenderer.php
M Widgets.php
2 files changed, 23 insertions(+), 22 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Widgets
refs/changes/49/189449/1
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: newchange
Gerrit-Change-Id: I00ede9c7f333f32f2cc7722781b06f97a544927f
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Widgets
Gerrit-Branch: master
Gerrit-Owner: Majr <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits