diff --git a/ChangeLog b/ChangeLog index 34d1338ce8f0..72d2cbc6c275 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,11 @@ $HeadURL: https://phpmyadmin.svn.sourceforge.net/svnroot/phpmyadmin/trunk/phpMyA 2.11.11.0 (not yet released) - [core] Fix broken cleanup of $_GET +2.11.10.1 (2010-08-20) +- [setup] Fixed output sanitizing in setup script, see PMASA-2010-4 for + more details. +- [core] Fixed various XSS issues, see PMASA-2010-5 for more details. + 2.11.10.0 (2009-12-07) - [core] safer handling of temporary files with open_basedir (thanks to Thijs Kinkhorst) diff --git a/db_sql.php b/db_sql.php index 6c582c3d3981..32d30e406cd4 100644 --- a/db_sql.php +++ b/db_sql.php @@ -36,7 +36,7 @@ /** * Query box, bookmark, insert data from textfile */ -PMA_sqlQueryForm(true, false, isset($_REQUEST['delimiter']) ? $_REQUEST['delimiter'] : ';'); +PMA_sqlQueryForm(true, false, isset($_REQUEST['delimiter']) ? htmlspecialchars($_REQUEST['delimiter']) : ';'); /** * Displays the footer diff --git a/error.php b/error.php index e0abb44574d9..750ac60e3ad1 100644 --- a/error.php +++ b/error.php @@ -73,10 +73,14 @@

phpMyAdmin -

diff --git a/libraries/common.lib.php b/libraries/common.lib.php index 626bbe386ed0..716af94d219f 100644 --- a/libraries/common.lib.php +++ b/libraries/common.lib.php @@ -473,7 +473,7 @@ function PMA_mysqlDie($error_message = '', $the_query = '', $formatted_sql = ''; } else { if (strlen($the_query) > $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) { - $formatted_sql = substr($the_query, 0, $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) . '[...]'; + $formatted_sql = htmlspecialchars(substr($the_query, 0, $GLOBALS['cfg']['MaxCharactersInDisplayedSQL'])) . '[...]'; } else { $formatted_sql = PMA_formatSql(PMA_SQP_parse($the_query), $the_query); } @@ -622,22 +622,23 @@ function PMA_convert_using($string, $mode='unquoted', $force_utf8 = false) function PMA_sendHeaderLocation($uri) { if (PMA_IS_IIS && strlen($uri) > 600) { + require_once './libraries/js_escape.lib.php'; echo '- - -' . "\n"; echo '' . "\n"; echo '' . "\n"; echo '' . "\n"; - echo '' . "\n"; + echo '' . "\n"; echo '' . "\n"; echo '' . "\n"; echo '' . "\n"; echo '' . "\n"; diff --git a/libraries/database_interface.lib.php b/libraries/database_interface.lib.php index 9a40c554b136..b7d122ce4be5 100644 --- a/libraries/database_interface.lib.php +++ b/libraries/database_interface.lib.php @@ -208,6 +208,10 @@ function PMA_usort_comparison_callback($a, $b) } else { $sorter = 'strcasecmp'; } + /* No sorting when key is not present */ + if (!isset($a[$GLOBALS['callback_sort_by']]) || ! isset($b[$GLOBALS['callback_sort_by']])) { + return 0; + } // produces f.e.: // return -1 * strnatcasecmp($a["SCHEMA_TABLES"], $b["SCHEMA_TABLES"]) return ($GLOBALS['callback_sort_order'] == 'ASC' ? 1 : -1) * $sorter($a[$GLOBALS['callback_sort_by']], $b[$GLOBALS['callback_sort_by']]); diff --git a/libraries/dbi/mysql.dbi.lib.php b/libraries/dbi/mysql.dbi.lib.php index 3ae84b803ab5..b0275b11ef67 100644 --- a/libraries/dbi/mysql.dbi.lib.php +++ b/libraries/dbi/mysql.dbi.lib.php @@ -300,6 +300,8 @@ function PMA_DBI_getError($link = null) $error_message = PMA_DBI_convert_message($error_message); } + $error_message = htmlspecialchars($error_message); + // Some errors messages cannot be obtained by mysql_error() if ($error_number == 2002) { $error = '#' . ((string) $error_number) . ' - ' . $GLOBALS['strServerNotResponding'] . ' ' . $GLOBALS['strSocketProblem']; diff --git a/libraries/dbi/mysqli.dbi.lib.php b/libraries/dbi/mysqli.dbi.lib.php index 705477ebf240..13b3eaf8838e 100644 --- a/libraries/dbi/mysqli.dbi.lib.php +++ b/libraries/dbi/mysqli.dbi.lib.php @@ -417,6 +417,8 @@ function PMA_DBI_getError($link = null) $error_message = PMA_DBI_convert_message($error_message); } + $error_message = htmlspecialchars($error_message); + if ($error_number == 2002) { $error = '#' . ((string) $error_number) . ' - ' . $GLOBALS['strServerNotResponding'] . ' ' . $GLOBALS['strSocketProblem']; } elseif (defined('PMA_MYSQL_INT_VERSION') && PMA_MYSQL_INT_VERSION >= 40100) { diff --git a/libraries/sanitizing.lib.php b/libraries/sanitizing.lib.php index 388ca1397526..3ba7224b90c6 100644 --- a/libraries/sanitizing.lib.php +++ b/libraries/sanitizing.lib.php @@ -7,17 +7,26 @@ /** * Sanitizes $message, taking into account our special codes - * for formatting + * for formatting. + * + * If you want to include result in element attribute, you should escape it. + * + * Examples: + * + *

+ * + * bar * * @uses preg_replace() * @uses strtr() * @param string the message + * @param boolean whether to escape html in result * * @return string the sanitized message * * @access public */ -function PMA_sanitize($message) +function PMA_sanitize($message, $escape = false) { $replace_pairs = array( '<' => '<', @@ -65,6 +74,10 @@ function PMA_sanitize($message) $message = preg_replace($pattern, '', $message); } + if ($escape) { + $message = htmlspecialchars($message); + } + return $message; } ?> diff --git a/libraries/sqlparser.lib.php b/libraries/sqlparser.lib.php index 488cde211bab..753f94cb6f73 100644 --- a/libraries/sqlparser.lib.php +++ b/libraries/sqlparser.lib.php @@ -2425,7 +2425,7 @@ function PMA_SQP_formatHtml($arr, $mode='color', $start_token=0, } $after .= "\n"; */ - $str .= $before . ($mode=='color' ? PMA_SQP_formatHTML_colorize($arr[$i]) : $arr[$i]['data']). $after; + $str .= $before . ($mode=='color' ? PMA_SQP_formatHTML_colorize($arr[$i]) : htmlspecialchars($arr[$i]['data'])). $after; } // end for if ($mode=='color') { $str .= ''; diff --git a/scripts/setup.php b/scripts/setup.php index 2f3d09d45ff2..49dd67bd18c3 100644 --- a/scripts/setup.php +++ b/scripts/setup.php @@ -518,6 +518,7 @@ function get_cfg_val($name, $val) { } } if ($type == 'string') { + $k = preg_replace('/[^A-Za-z0-9_]/', '_', $k); $ret .= get_cfg_val($name . "['$k']", $v); } elseif ($type == 'int') { $ret .= ' ' . PMA_var_export($v) . ',' . $crlf; diff --git a/server_databases.php b/server_databases.php index b9b8898b0e43..2b3e0a5de6ce 100644 --- a/server_databases.php +++ b/server_databases.php @@ -287,11 +287,11 @@ unset($column_order, $stat_name, $stat, $databases, $table_columns); if ($is_superuser || $cfg['AllowUserDropDatabase']) { - $common_url_query = PMA_generate_common_url() . '&sort_by=' . $sort_by . '&sort_order=' . $sort_order . '&dbstats=' . $dbstats; + $common_url_query = PMA_generate_common_url(array('sort_by' => $sort_by, 'sort_order' => $sort_order, 'dbstats' => $dbstats)); echo '' . $strWithChecked . '' . "\n" - . '' . "\n" + . '' . "\n" . ' ' . $strCheckAll . ' / ' . "\n" - . '' . "\n" + . '' . "\n" . ' ' . $strUncheckAll . '' . "\n" . '' . $strWithChecked . '' . "\n"; PMA_buttonOrImage('drop_selected_dbs', 'mult_submit', 'drop_selected_dbs', $strDrop, 'b_deltbl.png'); diff --git a/server_privileges.php b/server_privileges.php index 23d174b986d1..a030c5641cf0 100644 --- a/server_privileges.php +++ b/server_privileges.php @@ -602,7 +602,7 @@ function PMA_displayLoginInformationFields($mode = 'new', $indent = 0) { . $spaces . ' ' . "\n" . $spaces . ' ' . "\n" . $spaces . '' . "\n" - . $spaces . '' . "\n" + . $spaces . '' . "\n" . $spaces . '' . "\n" . $spaces . '
' . "\n" . $spaces . '
' . "\n" . $spaces . '
' . "\n" . $spaces . '