CVE-2014-7217: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Multiple cross-site scripting (XSS) vulnerabilities in phpMyAdmin 4.0.x before 4.0.10.4, 4.1.x before 4.1.14.5, and 4.2.x before 4.2.9.1 allow remote authenticated users to inject arbitrary web script or HTML via a crafted ENUM value that is improperly handled during rendering of the (1) table search or (2) table structure page, related to libraries/TableSearch.class.php and libraries/Util.class.php.
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Published: 2014-10-03T01:55Z
Repository: https://github.com/phpmyadmin/phpmyadmin
Language: PHP
Files changed: libraries/TableSearch.class.php, libraries/Util.class.php
Commit date: 2014-10-01 08:01:00 -0400
Commit message: [security] XSS with malicious ENUM values

Signed-off-by: Marc Delisle <marc@infomarc.info>

Conflicts:
	libraries/Util.class.php

Diff: diff --git a/libraries/TableSearch.class.php b/libraries/TableSearch.class.php
index d77cce1470fa..a0b3fa4924a7 100644
--- a/libraries/TableSearch.class.php
+++ b/libraries/TableSearch.class.php
@@ -314,10 +314,11 @@ private function _getForeignKeyInputBox($foreignData, $column_name,
      * @return string HTML elements.
      */
     private function _getEnumSetInputBox($column_index, $criteriaValues,
         $column_type, $column_id, $in_zoom_search_edit = false
     ) {
+        $column_type = htmlspecialchars($column_type);
         $html_output = '';
         $value = explode(
             ', ',
             str_replace("'", '', substr($column_type, 5, -1))
         );
@@ -983,26 +984,30 @@ private function _getRowsNormal()
             $html_output .= $this->_getGeomFuncHtml($column_index);
             //Displays column's name, type, collation and value
             $html_output .= '<th>'
                 . htmlspecialchars($this->_columnNames[$column_index]) . '</th>';
             $properties = $this->getColumnProperties($column_index, $column_index);
-            $html_output .= '<td>' . $properties['type'] . '</td>';
+            $html_output .= '<td>'
+                . htmlspecialchars($properties['type'])
+                . '</td>';
             $html_output .= '<td>' . $properties['collation'] . '</td>';
             $html_output .= '<td>' . $properties['func'] . '</td>';
             // here, the data-type attribute is needed for a date/time picker
             $html_output .= '<td data-type="' . $properties['type'] . '"'
                 . '>' . $properties['value'] . '</td>';
             $html_output .= '</tr>';
             //Displays hidden fields
             $html_output .= '<tr><td>';
             $html_output .= '<input type="hidden"'
                 . ' name="criteriaColumnNames[' . $column_index . ']"'
-                . ' value="' . htmlspecialchars($this->_columnNames[$column_index])
+                . ' value="'
+                . htmlspecialchars($this->_columnNames[$column_index])
                 . '" />';
             $html_output .= '<input type="hidden"'
                 . ' name="criteriaColumnTypes[' . $column_index . ']"'
-                . ' value="' . $this->_columnTypes[$column_index] . '" />';
+                . ' value="'
+                . htmlspecialchars($this->_columnTypes[$column_index]) . '" />';
             $html_output .= '<input type="hidden"'
                 . ' name="criteriaColumnCollations[' . $column_index . ']"'
                 . ' value="' . $this->_columnCollations[$column_index] . '" />';
             $html_output .= '</td></tr>';
         } // end for
diff --git a/libraries/Util.class.php b/libraries/Util.class.php
index 3154c3edc87b..44c1a0482083 100644
--- a/libraries/Util.class.php
+++ b/libraries/Util.class.php
@@ -3027,13 +3027,16 @@ public static function extractColumnSpec($columnspec)
         }
 
         // for the case ENUM('&#8211;','&ldquo;')
         $displayed_type = htmlspecialchars($printtype);
         if (strlen($printtype) > $GLOBALS['cfg']['LimitChars']) {
-            $displayed_type  = '<abbr title="' . $printtype . '">';
-            $displayed_type .= $GLOBALS['PMA_String']->substr(
-                $printtype, 0, $GLOBALS['cfg']['LimitChars']
+            $displayed_type  = '<abbr title="'
+                . htmlspecialchars($printtype) . '">';
+            $displayed_type .= htmlspecialchars(
+                $GLOBALS['PMA_String']->substr(
+                    $printtype, 0, $GLOBALS['cfg']['LimitChars']
+                )
             );
             $displayed_type .= '</abbr>';
         }
 
         return array(

Vulnerable code:             $html_output .= '<td>' . $properties['type'] . '</td>';
                . ' value="' . htmlspecialchars($this->_columnNames[$column_index])
                . ' value="' . $this->_columnTypes[$column_index] . '" />';
            $displayed_type  = '<abbr title="' . $printtype . '">';
            $displayed_type .= $GLOBALS['PMA_String']->substr(
                $printtype, 0, $GLOBALS['cfg']['LimitChars']
Fixed code:         $column_type = htmlspecialchars($column_type);
            $html_output .= '<td>'
                . htmlspecialchars($properties['type'])
                . '</td>';
                . ' value="'
                . htmlspecialchars($this->_columnNames[$column_index])
                . ' value="'
                . htmlspecialchars($this->_columnTypes[$column_index]) . '" />';
            $displayed_type  = '<abbr title="'
                . htmlspecialchars($printtype) . '">';
            $displayed_type .= htmlspecialchars(
                $GLOBALS['PMA_String']->substr(
                    $printtype, 0, $GLOBALS['cfg']['LimitChars']
                )