Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a7eacc1

Browse files
committedSep 1, 2011
Fix #13282, #13283: bug_actiongroup_ext_page.php LFI and XSS
High-Tech Bridge SA Security Research Lab reported 2 issues with the 'action' parameter to bug_actiongroup_ext_page.php Issue #13282 XSS issue with require_once() call failures returning an unescaped user-supplied filename. There has been a fair amount of recent public talk about PHP error messages being a source of XSS issues. This is an example. Issue #12283 Local file inclusion/path traversal vulnerability on web servers that allow translations like: http://example.com/directory/file.htm/../file2.htm ==> http://example.com/directory/file2.htm Vulnerable (default configuration): Apache Not vulnerable (default configuration): nginx This issue has _SEVERE_ consequences for people using web servers which don't check each segment of a path from top to bottom for validity. It shouldn't be possible to include the contents of config_inc.php to retrieve MantisBT database passwords because require_once('config_inc.php') will parse the document as a PHP script (echoing nothing). However it may allow attackers to view private files accessible to the web server user account. It also allows an attacker to guess the file structure of a server (existence of installed software, user accounts, etc). nginx will produce a 404 error when it determines that file.htm is not a directory. This makes too much sense, doesn't it?
1 parent b4af238 commit a7eacc1

File tree

2 files changed

+42
-8
lines changed

2 files changed

+42
-8
lines changed
 

‎bug_actiongroup_ext_page.php

+10-4
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,18 @@
4040
# redirect to view issues page if action doesn't have ext_* prefix.
4141
# This should only occur if this page is called directly.
4242
$t_external_action_prefix = 'EXT_';
43-
if ( strpos( $f_action, $t_external_action_prefix ) !== 0 ) {
43+
$t_matches = array();
44+
preg_match( '/^EXT_(\w+)$/', $f_action, $t_matches );
45+
if ( count( $t_matches ) !== 2 ) {
4446
print_header_redirect( 'view_all_bug_page.php' );
45-
}
47+
exit;
48+
}
49+
$t_external_action = $t_matches[1];
50+
$t_include_file = 'bug_actiongroup_' . $t_external_action . '_inc.php';
51+
if ( !file_exists( $t_include_file ) ) {
52+
trigger_error( ERROR_GENERIC, ERROR );
53+
}
4654

47-
$t_external_action = utf8_strtolower( utf8_substr( $f_action, utf8_strlen( $t_external_action_prefix ) ) );
48-
$t_form_fields_page = 'bug_actiongroup_' . $t_external_action . '_inc.php';
4955
$t_form_name = 'bug_actiongroup_' . $t_external_action;
5056

5157
bug_group_action_print_top();

‎core/bug_group_action_api.php

+32-4
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,14 @@ function bug_group_action_print_hidden_fields( $p_bug_ids_array ) {
9494
* @param $p_action The custom action name without the "EXT_" prefix.
9595
*/
9696
function bug_group_action_print_action_fields( $p_action ) {
97-
require_once( dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'bug_actiongroup_' . $p_action . '_inc.php' );
97+
if ( !preg_match( '/^\w+$/', $p_action ) ) {
98+
trigger_error( ERROR_GENERIC, ERROR );
99+
}
100+
$t_include_file = 'bug_actiongroup_' . $p_action . '_inc.php';
101+
if ( !file_exists( $t_include_file ) ) {
102+
trigger_error( ERROR_GENERIC, ERROR );
103+
}
104+
require_once( $t_include_file );
98105
$t_function_name = 'action_' . $p_action . '_print_fields';
99106
$t_function_name();
100107
}
@@ -106,7 +113,14 @@ function bug_group_action_print_action_fields( $p_action ) {
106113
* @param $p_action The custom action name without the "EXT_" prefix.
107114
*/
108115
function bug_group_action_print_title( $p_action ) {
109-
require_once( dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'bug_actiongroup_' . $p_action . '_inc.php' );
116+
if ( !preg_match( '/^\w+$/', $p_action ) ) {
117+
trigger_error( ERROR_GENERIC, ERROR );
118+
}
119+
$t_include_file = 'bug_actiongroup_' . $p_action . '_inc.php';
120+
if ( !file_exists( $t_include_file ) ) {
121+
trigger_error( ERROR_GENERIC, ERROR );
122+
}
123+
require_once( $t_include_file );
110124
$t_function_name = 'action_' . $p_action . '_print_title';
111125
$t_function_name();
112126
}
@@ -121,7 +135,14 @@ function bug_group_action_print_title( $p_action ) {
121135
* @returns true|array true if action can be applied or array of ( bug_id => reason for failure to validate )
122136
*/
123137
function bug_group_action_validate( $p_action, $p_bug_id ) {
124-
require_once( dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'bug_actiongroup_' . $p_action . '_inc.php' );
138+
if ( !preg_match( '/^\w+$/', $p_action ) ) {
139+
trigger_error( ERROR_GENERIC, ERROR );
140+
}
141+
$t_include_file = 'bug_actiongroup_' . $p_action . '_inc.php';
142+
if ( !file_exists( $t_include_file ) ) {
143+
trigger_error( ERROR_GENERIC, ERROR );
144+
}
145+
require_once( $t_include_file );
125146
$t_function_name = 'action_' . $p_action . '_validate';
126147
return $t_function_name( $p_bug_id );
127148
}
@@ -136,7 +157,14 @@ function bug_group_action_validate( $p_action, $p_bug_id ) {
136157
* @returns true|array Action can be applied., ( bug_id => reason for failure to process )
137158
*/
138159
function bug_group_action_process( $p_action, $p_bug_id ) {
139-
require_once( dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'bug_actiongroup_' . $p_action . '_inc.php' );
160+
if ( !preg_match( '/^\w+$/', $p_action ) ) {
161+
trigger_error( ERROR_GENERIC, ERROR );
162+
}
163+
$t_include_file = 'bug_actiongroup_' . $p_action . '_inc.php';
164+
if ( !file_exists( $t_include_file ) ) {
165+
trigger_error( ERROR_GENERIC, ERROR );
166+
}
167+
require_once( $t_include_file );
140168
$t_function_name = 'action_' . $p_action . '_process';
141169
return $t_function_name( $p_bug_id );
142170
}

0 commit comments

Comments
 (0)
Please sign in to comment.