CVE-2014-4986: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Multiple cross-site scripting (XSS) vulnerabilities in js/functions.js in phpMyAdmin 4.0.x before 4.0.10.1, 4.1.x before 4.1.14.2, and 4.2.x before 4.2.6 allow remote authenticated users to inject arbitrary web script or HTML via a crafted (1) table name or (2) column name that is improperly handled during construction of an AJAX confirmation message.
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-07-20T11:12Z
Repository: https://github.com/phpmyadmin/phpmyadmin
Language: JavaScript
Files changed: ChangeLog, js/functions.js, js/tbl_structure.js
Commit date: 2014-07-17 17:18:52 -0400
Commit message: bug #4492 [security] XSS in AJAX confirmation messages

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

Diff: diff --git a/ChangeLog b/ChangeLog
index 5a07d9023cb8..66c51992da8f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -13,10 +13,11 @@ phpMyAdmin - ChangeLog
 - bug #4483 'New window' link (selflink) disappears, causing Javascript error
 - bug #4489 Incorrect detection of privileges for routine creation
 - bug #4459 First few characters of database name aren't clickable when expanded
 - bug #4486 [security] XSS injection due to unescaped table comment
 - bug #4488 [security] XSS injection due to unescaped table name (triggers)
+- bug #4492 [security] XSS in AJAX confirmation messages
 
 4.2.5.0 (2014-06-26)
 - bug #4467 shell_exec() has been disabled for security reasons
 - bug #4470 Error while submitting empty query
 - bug #4463 Fatal error: Class 'PMA_DatabaseInterface' not found
diff --git a/js/functions.js b/js/functions.js
index b3e3d0f8ba03..ac6e0180c5a5 100644
--- a/js/functions.js
+++ b/js/functions.js
@@ -3546,11 +3546,11 @@ AJAX.registerOnload('functions.js', function () {
          * @var question    String containing the question to be asked for confirmation
          */
         var question = PMA_messages.strDropTableStrongWarning + ' ';
         question += $.sprintf(
             PMA_messages.strDoYouReally,
-            'DROP TABLE ' + PMA_commonParams.get('table')
+            'DROP TABLE ' + escapeHtml(PMA_commonParams.get('table'))
         );
 
         $(this).PMA_confirm(question, $(this).attr('href'), function (url) {
 
             var $msgbox = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
@@ -3612,11 +3612,11 @@ AJAX.registerOnload('functions.js', function () {
          * @var question    String containing the question to be asked for confirmation
          */
         var question = PMA_messages.strTruncateTableStrongWarning + ' ';
         question += $.sprintf(
             PMA_messages.strDoYouReally,
-            'TRUNCATE ' + PMA_commonParams.get('table')
+            'TRUNCATE ' + escapeHtml(PMA_commonParams.get('table'))
         );
         $(this).PMA_confirm(question, $(this).attr('href'), function (url) {
             PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
             $.get(url, {'is_js_confirmed': '1', 'ajax_request': true}, function (data) {
                 if ($("#sqlqueryresults").length !== 0) {
diff --git a/js/tbl_structure.js b/js/tbl_structure.js
index f754832c8ad2..9821cb312fed 100644
--- a/js/tbl_structure.js
+++ b/js/tbl_structure.js
@@ -196,10 +196,11 @@ AJAX.registerOnload('tbl_structure.js', function () {
         var $curr_row = $(this).parents('tr');
         /**
          * @var curr_column_name    String containing name of the field referred to by {@link curr_row}
          */
         var curr_column_name = $curr_row.children('th').children('label').text();
+        curr_column_name = escapeHtml(curr_column_name);
         /**
          * @var $after_field_item    Corresponding entry in the 'After' field.
          */
         var $after_field_item = $("select[name='after_field'] option[value='" + curr_column_name + "']");
         /**

Vulnerable code:             'DROP TABLE ' + PMA_commonParams.get('table')
            'TRUNCATE ' + PMA_commonParams.get('table')
Fixed code: - bug #4492 [security] XSS in AJAX confirmation messages
            'DROP TABLE ' + escapeHtml(PMA_commonParams.get('table'))
            'TRUNCATE ' + escapeHtml(PMA_commonParams.get('table'))
        curr_column_name = escapeHtml(curr_column_name);