CVE-2016-5364: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Cross-site scripting (XSS) vulnerability in manage_custom_field_edit_page.php in MantisBT 1.2.19 and earlier allows remote attackers to inject arbitrary web script or HTML via the return parameter.
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
CVSS v3 base score: 6.1
Published: 2017-02-17T17:59Z
Repository: https://github.com/mantisbt/mantisbt
Language: PHP
Files changed: core/html_api.php, manage_custom_field_edit_page.php
Commit date: 2016-06-11 02:01:33 +0200
Commit message: Fix XSS in custom fields management

Kacper Szurek (http://security.szurek.pl/) discovered an XSS
vulnerability in Custom fields management pages, caused by unescaped
output of 'return URL' GPC parameter. His report describes two ways to
exploit this issue:

1. using 'accesskey' inside hidden input field (see [1]) reflects XSS to
   the administrator in manage_custom_field_edit_page.php when the
   keyboard shortcut is actioned
2. using 'javascript:' URI scheme executes the code when the user clicks
   the [Proceed] link on manage_custom_field_update.php after updating
   a custom field

This commit fixes both attack vectors:

- properly escape the return URL prior to printing it on the hidden form
  field
- let html_operation_successful() sanitize the URL before displaying
  it, just like html_meta_redirect() does. In this case, if the
  string contains an URI scheme, it will be replaced by 'index.php'

[1] http://blog.portswigger.net/2015/11/xss-in-hidden-input-fields.html

Fixes #20956

Diff: diff --git a/core/html_api.php b/core/html_api.php
index b8a3ac3eff..55696e3a15 100644
--- a/core/html_api.php
+++ b/core/html_api.php
@@ -645,11 +645,11 @@ function html_operation_successful( $p_redirect_url, $p_message = '' ) {
 	if( !is_blank( $p_message ) ) {
 		echo $p_message . '<br />';
 	}
 
 	echo lang_get( 'operation_successful' ).'<br />';
-	print_bracket_link( $p_redirect_url, lang_get( 'proceed' ) );
+	print_bracket_link( string_sanitize_url( $p_redirect_url ), lang_get( 'proceed' ) );
 	echo '</div>';
 }
 
 /**
  * Checks if the current page load was triggered by auto-refresh or real activity
diff --git a/manage_custom_field_edit_page.php b/manage_custom_field_edit_page.php
index 008d457d52..b29cfd6380 100644
--- a/manage_custom_field_edit_page.php
+++ b/manage_custom_field_edit_page.php
@@ -71,11 +71,11 @@ $t_definition = custom_field_get_definition( $f_field_id );
 	<form id="manage-custom-field-update-form" method="post" action="manage_custom_field_update.php">
 		<fieldset>
 			<legend><span><?php echo lang_get( 'edit_custom_field_title' ) ?></span></legend>
 			<?php echo form_security_field( 'manage_custom_field_update' ); ?>
 			<input type="hidden" name="field_id" value="<?php echo $f_field_id ?>" />
-			<input type="hidden" name="return" value="<?php echo $f_return ?>" />
+			<input type="hidden" name="return" value="<?php echo string_attribute( $f_return ); ?>" />
 			<div class="field-container">
 				<label for="custom-field-name"><span><?php echo lang_get( 'custom_field_name' ) ?></span></label>
 				<span class="input"><input type="text" id="custom-field-name" name="name" size="32" maxlength="64" value="<?php echo string_attribute( $t_definition['name'] ) ?>" /></span>
 				<span class="label-style"></span>
 			</div>

Vulnerable code: 	print_bracket_link( $p_redirect_url, lang_get( 'proceed' ) );
			<input type="hidden" name="return" value="<?php echo $f_return ?>" />
Fixed code: 	print_bracket_link( string_sanitize_url( $p_redirect_url ), lang_get( 'proceed' ) );
			<input type="hidden" name="return" value="<?php echo string_attribute( $f_return ); ?>" />