Vulnerability: The print_test_result function in admin/upgrade_unattended.php in MantisBT 1.1.0a3 through 1.2.x before 1.2.18 allows remote attackers to obtain database credentials via a URL in the hostname parameter and reading the parameters in the response sent to the URL.
Vulnerability ID: CVE-2014-9279
CWE: CWE-200
Severity score: 2.9
Project: https://github.com/mantisbt/mantisbt
Published: 2014-12-08
File: admin/upgrade_unattended.php
Commit message: DB Credentials leak in upgrade_unattended.php

Retrieve credentials from Mantis system configuration instead of
accepting them from POST parameters.

This issue was reported by Matthias Karlsson (http://mathiaskarlsson.me)
as part of Offensive Security's bug bounty program [1].

Paul Richards' original patch was modified to align the code with master
branch to (basically replacing DIRECTORY_SEPARATOR by '/') to facilitate
porting.

Fixes #17877

[1] http://www.offensive-security.com/bug-bounty-program/

Signed-off-by: Damien Regad <dregad@mantisbt.org>
Commit author: Damien Regad

Vulnerable version (before fix):
 function print_test_result( $p_result, $p_hard_fail = true, $p_message = '' ) { }  # read control variables with defaults $f_hostname = gpc_get( 'hostname', config_get( 'hostname', 'localhost' ) ); $f_db_type = gpc_get( 'db_type', config_get( 'db_type', '' ) ); $f_database_name = gpc_get( 'database_name', config_get( 'database_name', 'bugtrack' ) ); $f_db_username = gpc_get( 'db_username', config_get( 'db_username', '' ) ); $f_db_password = gpc_get( 'db_password', config_get( 'db_password', '' ) ); $f_db_exists = gpc_get_bool( 'db_exists', false );  # install the tables if ( !preg_match( '/^[a-zA-Z0-9_]+$/', $f_db_type ) ||      !file_exists( dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'library' . DIRECTORY_SEPARATOR . 'adodb' . DIRECTORY_SEPARATOR . 'drivers' . DIRECTORY_SEPARATOR . 'adodb-' . $f_db_type . '.inc.php' ) ) { 	echo 'Invalid db type ' . htmlspecialchars( $f_db_type ) . '.'; 	exit; }  $GLOBALS['g_db_type'] = $f_db_type; # database_api references this require_once( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'schema.php' ); $g_db = ADONewConnection( $f_db_type );  echo "\nPost 1.0 schema changes\n"; echo "Connecting to database... "; $t_result = @$g_db->Connect( $f_hostname, $f_db_username, $f_db_password, $f_database_name );  if( false == $t_result ) { 	echo "Failed.\n";

Fixed version (after fix):
 function print_test_result( $p_result, $p_hard_fail = true, $p_message = '' ) { }  # read control variables with defaults $t_db_type = config_get_global( 'db_type' );  # install the tables if( !preg_match( '/^[a-zA-Z0-9_]+$/', $f_db_type ) || 	!file_exists( dirname( dirname( __FILE__ ) ) . '/library/adodb/drivers/adodb-' . $t_db_type . '.inc.php' ) ) { 	echo 'Invalid db type ' . htmlspecialchars( $t_db_type ) . '.'; 	exit; }  $GLOBALS['g_db_type'] = $t_db_type; # database_api references this require_once( dirname( __FILE__ ) . '/schema.php' ); $g_db = ADONewConnection( $t_db_type );  echo "\nPost 1.0 schema changes\n"; echo "Connecting to database... "; $t_result = @$g_db->Connect( config_get_global( 'hostname' ), config_get_global( 'db_username' ), config_get_global( 'db_password' ), config_get_global( 'database_name' ) );  if( false == $t_result ) { 	echo "Failed.\n";

Patch:
patch: @@ -94,27 +94,22 @@ function print_test_result( $p_result, $p_hard_fail = true, $p_message = '' ) {
 }
 
 # read control variables with defaults
-$f_hostname = gpc_get( 'hostname', config_get( 'hostname', 'localhost' ) );
-$f_db_type = gpc_get( 'db_type', config_get( 'db_type', '' ) );
-$f_database_name = gpc_get( 'database_name', config_get( 'database_name', 'bugtrack' ) );
-$f_db_username = gpc_get( 'db_username', config_get( 'db_username', '' ) );
-$f_db_password = gpc_get( 'db_password', config_get( 'db_password', '' ) );
-$f_db_exists = gpc_get_bool( 'db_exists', false );
+$t_db_type = config_get_global( 'db_type' );
 
 # install the tables
-if ( !preg_match( '/^[a-zA-Z0-9_]+$/', $f_db_type ) ||
-     !file_exists( dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'library' . DIRECTORY_SEPARATOR . 'adodb' . DIRECTORY_SEPARATOR . 'drivers' . DIRECTORY_SEPARATOR . 'adodb-' . $f_db_type . '.inc.php' ) ) {
-	echo 'Invalid db type ' . htmlspecialchars( $f_db_type ) . '.';
+if( !preg_match( '/^[a-zA-Z0-9_]+$/', $f_db_type ) ||
+	!file_exists( dirname( dirname( __FILE__ ) ) . '/library/adodb/drivers/adodb-' . $t_db_type . '.inc.php' ) ) {
+	echo 'Invalid db type ' . htmlspecialchars( $t_db_type ) . '.';
 	exit;
 }
 
-$GLOBALS['g_db_type'] = $f_db_type; # database_api references this
-require_once( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'schema.php' );
-$g_db = ADONewConnection( $f_db_type );
+$GLOBALS['g_db_type'] = $t_db_type; # database_api references this
+require_once( dirname( __FILE__ ) . '/schema.php' );
+$g_db = ADONewConnection( $t_db_type );
 
 echo "\nPost 1.0 schema changes\n";
 echo "Connecting to database... ";
-$t_result = @$g_db->Connect( $f_hostname, $f_db_username, $f_db_password, $f_database_name );
+$t_result = @$g_db->Connect( config_get_global( 'hostname' ), config_get_global( 'db_username' ), config_get_global( 'db_password' ), config_get_global( 'database_name' ) );
 
 if( false == $t_result ) {
 	echo "Failed.\n";
path: admin/upgrade_unattended.php