CVE-2018-20322: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: LimeSurvey version 3.15.5 contains a Cross-site scripting (XSS) vulnerability in Survey Resource zip upload, resulting in Javascript code execution against LimeSurvey administrators. Fixed in version 3.15.6.
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.
CVSS v3 base score: 6.1
Published: 2018-12-21T23:29Z
Repository: https://github.com/LimeSurvey/LimeSurvey
Language: PHP
Files changed: application/views/admin/survey/importSurveyResources_view.php, application/views/admin/themes/importuploaded_view.php, application/views/admin/themes/templatesummary_view.php
Commit date: 2018-12-21 12:38:10 +0100
Commit message: [security] Fixed issue #14376: XSS in Survey Resource zip upload
[security] Fixed issue : XSS in theme zip upload
Dev: CHtml::encode filename (whole) when view
Dev: Same with import theme
Dev: some other fix to do : reporting issues

Diff: diff --git a/application/views/admin/survey/importSurveyResources_view.php b/application/views/admin/survey/importSurveyResources_view.php
index bbd22ce5a89..ebfbbdd3143 100644
--- a/application/views/admin/survey/importSurveyResources_view.php
+++ b/application/views/admin/survey/importSurveyResources_view.php
@@ -17,13 +17,12 @@
                     <strong><?php eT("Imported Files List") ?>:</strong>
                 </p>
                 <p>
                     <ul>
                         <?php
-                        foreach ($aImportedFilesInfo as $entry)
-                        {
-                            echo CHtml::tag('li', array(), gT("File") . ': ' . $entry["filename"]);
+                        foreach ($aImportedFilesInfo as $entry) {
+                            echo CHtml::tag('li', array(), sprintf(gT("File: %s"),CHtml::encode($entry["filename"])));
                         }
                         ?>
                     </ul>
                 </p>
                 <p>
@@ -53,25 +52,23 @@
                         <strong><?php eT("Imported Files List"); ?>:</strong>
                     </p>
                     <p>
                         <ul>
                             <?php
-                            foreach ($aImportedFilesInfo as $entry)
-                            {
-                                echo CHtml::tag('li', array(), gT("File") . ': ' . $entry["filename"]);
+                            foreach ($aImportedFilesInfo as $entry) {
+                                echo CHtml::tag('li', array(), sprintf(gT("File: %s"),CHtml::encode($entry["filename"])));
                             }
                             ?>
                         </ul>
                     </p>
                     <p>
                         <strong class="text-warning"><?php eT("Error Files List"); ?>:</strong>
                     </p>
                     <p>
                         <?php
-                            foreach ($aErrorFilesInfo as $entry)
-                            {
-                                echo CHtml::tag('li', array(), gT("File") . ': ' . $entry['filename'] . " (" . $entry['status'] . ")");
+                            foreach ($aErrorFilesInfo as $entry) {
+                                echo CHtml::tag('li', array(), sprintf(gT("File: %s (%s)"),CHtml::encode($entry["filename"]),$entry['status']));
                             }
                         ?>
                         </ul>
                     </p>
                     <p>
@@ -100,13 +97,12 @@
                     <p>
                         <strong class="text-warning"><?php eT("Error Files List"); ?>:</strong>
                     </p>
                     <p>
                         <?php
-                            foreach ($aErrorFilesInfo as $entry)
-                            {
-                                echo CHtml::tag('li', array(), gT("File") . ': ' . $entry['filename'] . " (" . $entry['status'] . ")");
+                            foreach ($aErrorFilesInfo as $entry) {
+                                echo CHtml::tag('li', array(), sprintf(gT("File: %s (%s)"),CHtml::encode($entry["filename"]),$entry['status']));
                             }
                         ?>
                         </ul>
                     </p>
                     <p>
diff --git a/application/views/admin/themes/importuploaded_view.php b/application/views/admin/themes/importuploaded_view.php
index abd2ddb310f..88d023c2d05 100644
--- a/application/views/admin/themes/importuploaded_view.php
+++ b/application/views/admin/themes/importuploaded_view.php
@@ -50,16 +50,16 @@
                         <?php
                             foreach ($aImportedFilesInfo as $entry)
                             {
                                 if ($entry['is_folder']){
                                 ?>
-                                <li><?php echo gT("Folder:") . " " . htmlspecialchars($entry["filename"],ENT_QUOTES,'utf-8'); ?></li>
+                                <li><?php printf(gT("Folder: %s"),CHtml::encode($entry["filename"])); ?></li>
                                 <?php
                                 }
                                 else
                                 { ?>
-                                <li><?php echo gT("File:") . " " . htmlspecialchars($entry["filename"],ENT_QUOTES,'utf-8'); ?></li>
+                                <li><?php printf(gT("File: %s"),CHtml::encode($entry["filename"])); ?></li>
 
 
                                 <?php
                                 }
                             }
@@ -72,11 +72,11 @@
                     <ul style="max-height: 250px; overflow-y:scroll;" class="list-unstyled">
                         <?php
                             foreach ($aErrorFilesInfo as $entry)
                             {
                             ?>
-                            <li><?php echo gT("File:") . " " . $entry["filename"] ?></li>
+                            <li><?php printf(gT("File: %s"),CHtml::encode($entry["filename"])); ?></li>
                             <?php
                             }
                         }
                     ?>
                 </ul>
diff --git a/application/views/admin/themes/templatesummary_view.php b/application/views/admin/themes/templatesummary_view.php
index e8f9d8b5a8c..8cbccb4241c 100644
--- a/application/views/admin/themes/templatesummary_view.php
+++ b/application/views/admin/themes/templatesummary_view.php
@@ -124,11 +124,11 @@ Yii::app()->getClientScript()->registerScript('editorfiletype',"editorfiletype =
             <br/>
             <div class="col-sm-12 well other-files-list">
                 <?php foreach ($otherfiles as $fileName => $file) { ?>
                     <div class="row other-files-row">
                         <div class="col-sm-9 other-files-filename">
-                            <?php echo (empty(substr(strrchr($file, DIRECTORY_SEPARATOR), 1)))?$file:substr(strrchr($file, DIRECTORY_SEPARATOR), 1) ;?>
+                            <?php echo CHtml::encode((empty(substr(strrchr($file, DIRECTORY_SEPARATOR), 1)))?$file:substr(strrchr($file, DIRECTORY_SEPARATOR), 1)) ;?>
                         </div>
                         <div class="col-sm-3">
                             <?php //TODO: make it ajax and less messy ?>
                             <?php if ( $oEditedTemplate->getTemplateForFile($fileName, $oEditedTemplate)->sTemplateName == $oEditedTemplate->sTemplateName) {
                                 if (Permission::model()->hasGlobalPermission('templates','delete')) { ?>

Vulnerable code:                         foreach ($aImportedFilesInfo as $entry)
                        {
                            echo CHtml::tag('li', array(), gT("File") . ': ' . $entry["filename"]);
                            foreach ($aImportedFilesInfo as $entry)
                            {
                                echo CHtml::tag('li', array(), gT("File") . ': ' . $entry["filename"]);
                            foreach ($aErrorFilesInfo as $entry)
                            {
                                echo CHtml::tag('li', array(), gT("File") . ': ' . $entry['filename'] . " (" . $entry['status'] . ")");
                            foreach ($aErrorFilesInfo as $entry)
                            {
                                echo CHtml::tag('li', array(), gT("File") . ': ' . $entry['filename'] . " (" . $entry['status'] . ")");
                                <li><?php echo gT("Folder:") . " " . htmlspecialchars($entry["filename"],ENT_QUOTES,'utf-8'); ?></li>
                                <li><?php echo gT("File:") . " " . htmlspecialchars($entry["filename"],ENT_QUOTES,'utf-8'); ?></li>
                            <li><?php echo gT("File:") . " " . $entry["filename"] ?></li>
                            <?php echo (empty(substr(strrchr($file, DIRECTORY_SEPARATOR), 1)))?$file:substr(strrchr($file, DIRECTORY_SEPARATOR), 1) ;?>
Fixed code:                         foreach ($aImportedFilesInfo as $entry) {
                            echo CHtml::tag('li', array(), sprintf(gT("File: %s"),CHtml::encode($entry["filename"])));
                            foreach ($aImportedFilesInfo as $entry) {
                                echo CHtml::tag('li', array(), sprintf(gT("File: %s"),CHtml::encode($entry["filename"])));
                            foreach ($aErrorFilesInfo as $entry) {
                                echo CHtml::tag('li', array(), sprintf(gT("File: %s (%s)"),CHtml::encode($entry["filename"]),$entry['status']));
                            foreach ($aErrorFilesInfo as $entry) {
                                echo CHtml::tag('li', array(), sprintf(gT("File: %s (%s)"),CHtml::encode($entry["filename"]),$entry['status']));
                                <li><?php printf(gT("Folder: %s"),CHtml::encode($entry["filename"])); ?></li>
                                <li><?php printf(gT("File: %s"),CHtml::encode($entry["filename"])); ?></li>
                            <li><?php printf(gT("File: %s"),CHtml::encode($entry["filename"])); ?></li>
                            <?php echo CHtml::encode((empty(substr(strrchr($file, DIRECTORY_SEPARATOR), 1)))?$file:substr(strrchr($file, DIRECTORY_SEPARATOR), 1)) ;?>