Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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?
  • Loading branch information...
commit a7eacc181185eff1dd7bd8ceaa34a91cf86cc298 1 parent b4af238
David Hicks authored September 01, 2011
14  bug_actiongroup_ext_page.php
@@ -40,12 +40,18 @@
40 40
   # redirect to view issues page if action doesn't have ext_* prefix.
41 41
   # This should only occur if this page is called directly.
42 42
 	$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 ) {
44 46
 		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
+	}
46 54
 
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';
49 55
 	$t_form_name = 'bug_actiongroup_' . $t_external_action;
50 56
 
51 57
 	bug_group_action_print_top();
36  core/bug_group_action_api.php
@@ -94,7 +94,14 @@ function bug_group_action_print_hidden_fields( $p_bug_ids_array ) {
94 94
  * @param $p_action   The custom action name without the "EXT_" prefix.
95 95
  */
96 96
 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 );
98 105
 	$t_function_name = 'action_' . $p_action . '_print_fields';
99 106
 	$t_function_name();
100 107
 }
@@ -106,7 +113,14 @@ function bug_group_action_print_action_fields( $p_action ) {
106 113
  * @param $p_action   The custom action name without the "EXT_" prefix.
107 114
  */
108 115
 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 );
110 124
 	$t_function_name = 'action_' . $p_action . '_print_title';
111 125
 	$t_function_name();
112 126
 }
@@ -121,7 +135,14 @@ function bug_group_action_print_title( $p_action ) {
121 135
  * @returns true|array true if action can be applied or array of ( bug_id => reason for failure to validate )
122 136
  */
123 137
 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 );
125 146
 	$t_function_name = 'action_' . $p_action . '_validate';
126 147
 	return $t_function_name( $p_bug_id );
127 148
 }
@@ -136,7 +157,14 @@ function bug_group_action_validate( $p_action, $p_bug_id ) {
136 157
  * @returns true|array Action can be applied., ( bug_id => reason for failure to process )
137 158
  */
138 159
 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 );
140 168
 	$t_function_name = 'action_' . $p_action . '_process';
141 169
 	return $t_function_name( $p_bug_id );
142 170
 }

0 notes on commit a7eacc1

Please sign in to comment.
Something went wrong with that request. Please try again.