CVE-2023-2103: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Cross-site Scripting (XSS) - Stored in GitHub repository alextselegidis/easyappointments prior to 1.5.0.
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: 5.4
Published: 2023-04-15T14:15Z
Repository: https://github.com/alextselegidis/easyappointments
Language: PHP
Files changed: application/views/components/booking_type_step.php, application/views/components/cookie_notice_modal.php, application/views/components/privacy_policy_modal.php, application/views/components/terms_and_conditions_modal.php, assets/js/pages/booking.js
Commit date: 2023-04-15 14:14:42 +0200
Commit message: Escape the legal settings, service and category name in the booking page

Diff: diff --git a/application/views/components/booking_type_step.php b/application/views/components/booking_type_step.php
index 959726571..e87ab41ca 100644
--- a/application/views/components/booking_type_step.php
+++ b/application/views/components/booking_type_step.php
@@ -1,9 +1,9 @@
 <?php
 /**
  * Local variables.
- * 
+ *
  * @var array $available_services
  */
 ?>
 
 <div id="wizard-frame-1" class="wizard-frame" style="visibility: hidden;">
@@ -64,25 +64,25 @@
                                     ? $group[0]['category_name']
                                     : 'Uncategorized';
 
                                 if (count($group) > 0)
                                 {
-                                    echo '<optgroup label="' . $group_label . '">';
+                                    echo '<optgroup label="' . e($group_label) . '">';
                                     foreach ($group as $service)
                                     {
                                         echo '<option value="' . $service['id'] . '">'
-                                            . $service['name'] . '</option>';
+                                            . e($service['name']) . '</option>';
                                     }
                                     echo '</optgroup>';
                                 }
                             }
                         }
                         else
                         {
                             foreach ($available_services as $service)
                             {
-                                echo '<option value="' . $service['id'] . '">' . $service['name'] . '</option>';
+                                echo '<option value="' . $service['id'] . '">' . e($service['name']) . '</option>';
                             }
                         }
                         ?>
                     </select>
                 </div>
diff --git a/application/views/components/cookie_notice_modal.php b/application/views/components/cookie_notice_modal.php
index a800aaf3c..36d90e7e9 100644
--- a/application/views/components/cookie_notice_modal.php
+++ b/application/views/components/cookie_notice_modal.php
@@ -11,11 +11,11 @@
             <div class="modal-header">
                 <h4 class="modal-title"><?= lang('cookie_notice') ?></h4>
                 <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
             </div>
             <div class="modal-body">
-                <p><?= $cookie_notice_content ?></p>
+                <p><?= e($cookie_notice_content) ?></p>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
                     <?= lang('close') ?>
                 </button>
diff --git a/application/views/components/privacy_policy_modal.php b/application/views/components/privacy_policy_modal.php
index 1590587bd..3db0749f0 100644
--- a/application/views/components/privacy_policy_modal.php
+++ b/application/views/components/privacy_policy_modal.php
@@ -13,11 +13,11 @@
                 <h4 class="modal-title"><?= lang('privacy_policy') ?></h4>
                 <button type="button" class="btn-close" data-bs-dismiss="modal"><span aria-hidden="true"></span>
                 </button>
             </div>
             <div class="modal-body">
-                <p><?= $privacy_policy_content ?></p>
+                <p><?= e($privacy_policy_content) ?></p>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
                     <?= lang('close') ?>
                 </button>
diff --git a/application/views/components/terms_and_conditions_modal.php b/application/views/components/terms_and_conditions_modal.php
index cdcf8e68d..37eee4bc4 100644
--- a/application/views/components/terms_and_conditions_modal.php
+++ b/application/views/components/terms_and_conditions_modal.php
@@ -12,11 +12,11 @@
             <div class="modal-header">
                 <h4 class="modal-title"><?= lang('terms_and_conditions') ?></h4>
                 <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
             </div>
             <div class="modal-body">
-                <p><?= $terms_and_conditions_content ?></p>
+                <p><?= e($terms_and_conditions_content) ?></p>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
                     <?= lang('close') ?>
                 </button>
diff --git a/assets/js/pages/booking.js b/assets/js/pages/booking.js
index c6319ffd6..df4d5e26e 100644
--- a/assets/js/pages/booking.js
+++ b/assets/js/pages/booking.js
@@ -801,11 +801,11 @@ App.Pages.Booking = (function () {
         if (!service) {
             return;
         }
 
         $('<strong/>', {
-            'text': service.name
+            'text': App.Utils.String.escapeHtml(service.name),
         }).appendTo($serviceDescription);
 
         if (service.description) {
             $('<br/>').appendTo($serviceDescription);
 

Vulnerable code:  * 
                                    echo '<optgroup label="' . $group_label . '">';
                                            . $service['name'] . '</option>';
                                echo '<option value="' . $service['id'] . '">' . $service['name'] . '</option>';
                <p><?= $cookie_notice_content ?></p>
                <p><?= $privacy_policy_content ?></p>
                <p><?= $terms_and_conditions_content ?></p>
            'text': service.name
Fixed code:  *
                                    echo '<optgroup label="' . e($group_label) . '">';
                                            . e($service['name']) . '</option>';
                                echo '<option value="' . $service['id'] . '">' . e($service['name']) . '</option>';
                <p><?= e($cookie_notice_content) ?></p>
                <p><?= e($privacy_policy_content) ?></p>
                <p><?= e($terms_and_conditions_content) ?></p>
            'text': App.Utils.String.escapeHtml(service.name),