User:CSteipp (WMF)/SuperVulnerableExtension

This is a demo extension with various vulnerabilities. Use this to practice exploiting issues, don't use it for anything else!

You should be able to find and exploit,

  • 2 reflected xss
  • 1 dom xss
  • 1 sqli
  • 2 info leaks
$wgSpecialPages['SVE'] = 'SpecialSVE';

$wgResourceModules['ext.sve'] = array(
	'scripts' => 'ext.sve.js',
	'position' => 'top',
	'targets' => array( 'mobile', 'desktop' ),
	'localBasePath' => __DIR__ . '/modules',
	'remoteExtPath' => 'SuperVulnerableExtension/modules',
);

class SpecialSVE extends SpecialPage {

	public function __construct() {
		parent::__construct( 'SVE' );
	}

	public function execute( $par ) {
		$this->getOutput()->addModules( 'ext.sve' );
		$req = $this->getRequest();
		if ( !$par ) {
			$par = $req->getVal( 'svesearch' );
		}

		$this->showSearchForm( $par );
		$this->showResultTable( $par );
	}


	private function showSearchForm( $par ) {

		$url = $this->getTitle()->getLocalURL();

		if ( $par ) {
			$this->getOutput()->setSubtitle( "Searched for <b>$par</b>" );
		}

		$par = htmlspecialchars( $par );

		$this->getOutput()->addHtml(
			"<form action='$url'>"
			. "<input type='text' name='svesearch' value='$par' autocomplete='off' />"
			. "<input type='hidden' name='title' value='Special:SVE' />"
			. "<input type='submit' name='svesubmit' value='Go' />"
			. "</form>"
		);
	}

	private function showResultTable( $par ) {
		$html = '';
		$dbr = wfGetDB( DB_SLAVE );
		$par = str_replace( "'", "\'", $par );
		$result = $dbr->select(
			'user',
			'*',
			"user_name > '$par'",
			__METHOD__,
			array( 'LIMIT' => 5 )
		);

		// Build table
		$html .= '<table id="sveListOfNames" class="wikitable">';
		$html .= '<tr><th>id</th><th>name</th><th>famous?</th></tr>';
		foreach ( $result as $row ) {
			$html .= '<tr>';
			$html .= Html::element( 'td', array(), $row->user_id );
			$html .= Html::element(
				'td',
				array(
					'class' => 'username',
					'data-username' => $row->user_name,
					'data-email' => $row->user_email,
				),
				$row->user_name
			);
			$html .= Html::rawElement(
				'td',
				array(),
				Html::element(
					'a',
					array(
						'href' => $row->user_name,
					),
					$row->user_name
				)
			);
			$html .= '</tr>';
		}
		$html .= '</table>';

		$this->getOutput()->addHtml( $html );
	}

}

ext.sve.js:

( function ( mw, $ ) {
	$( '.username' ).filter(
		function() {
			var uname = $(this).data('username');
			var uemail = $(this).data('email');
			if ( uemail ) {
				$(this).html( "<a href='mailto:"+uemail+"'>"+uname+'</a>' );
			}
		}
	);
}( mediaWiki, jQuery ) );