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 '' . "\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 . '