CVE-2023-1367: Improper Control of Generation of Code ('Code Injection') (CWE-94)
value: Code Injection in GitHub repository alextselegidis/easyappointments prior to 1.5.0.
CWE description: The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.
CVSS v3 base score: 3.8
Published: 2023-03-13T09:15Z
Repository: https://github.com/alextselegidis/easyappointments
Language: PHP
Files changed: application/views/components/appointments_modal.php, application/views/components/backend_footer.php, application/views/components/google_analytics_script.php, application/views/components/matomo_analytics_script.php, application/views/emails/account_recovery_email.php, application/views/emails/appointment_deleted_email.php, application/views/emails/appointment_saved_email.php
Commit date: 2023-03-13 08:18:39 +0100
Commit message: Apply the new escape helper function to the view files

Diff: diff --git a/application/views/components/appointments_modal.php b/application/views/components/appointments_modal.php
index ae5ce7ce2..b72376cfa 100644
--- a/application/views/components/appointments_modal.php
+++ b/application/views/components/appointments_modal.php
@@ -41,10 +41,11 @@
                                     <select id="select-service" class="required form-control">
                                         <?php
                                         // Group services by category, only if there is at least one service
                                         // with a parent category.
                                         $has_category = FALSE;
+                                        
                                         foreach ($available_services as $service)
                                         {
                                             if ( ! empty($service['category_id']))
                                             {
                                                 $has_category = TRUE;
@@ -70,10 +71,11 @@
                                             }
 
                                             // We need the uncategorized services at the end of the list, so we will use
                                             // another iteration only for the uncategorized services.
                                             $grouped_services['uncategorized'] = [];
+                                            
                                             foreach ($available_services as $service)
                                             {
                                                 if ($service['category_id'] == NULL)
                                                 {
                                                     $grouped_services['uncategorized'][] = $service;
@@ -81,21 +83,21 @@
                                             }
 
                                             foreach ($grouped_services as $key => $group)
                                             {
                                                 $group_label = $key !== 'uncategorized'
-                                                    ? $group[0]['category_name']
+                                                    ? e($group[0]['category_name'])
                                                     : 'Uncategorized';
 
                                                 if (count($group) > 0)
                                                 {
                                                     echo '<optgroup label="' . $group_label . '">';
 
                                                     foreach ($group as $service)
                                                     {
                                                         echo '<option value="' . $service['id'] . '">'
-                                                            . $service['name'] . '</option>';
+                                                            . e($service['name']) . '</option>';
                                                     }
 
                                                     echo '</optgroup>';
                                                 }
                                             }
@@ -103,11 +105,11 @@
                                         else
                                         {
                                             foreach ($available_services as $service)
                                             {
                                                 echo '<option value="' . $service['id'] . '">'
-                                                    . $service['name'] . '</option>';
+                                                    . e($service['name']) . '</option>';
                                             }
                                         }
                                         ?>
                                     </select>
                                 </div>
@@ -135,12 +137,12 @@
                                     <label for="appointment-status" class="form-label">
                                         <?= lang('status') ?>
                                     </label>
                                     <select id="appointment-status" class="form-control">
                                         <?php foreach ($appointment_status_options as $appointment_status_option): ?>
-                                            <option value="<?= $appointment_status_option ?>">
-                                                <?= $appointment_status_option ?>
+                                            <option value="<?= e($appointment_status_option) ?>">
+                                                <?= e($appointment_status_option) ?>
                                             </option>
                                         <?php endforeach ?>
                                     </select>
                                 </div>
                             </div>
diff --git a/application/views/components/backend_footer.php b/application/views/components/backend_footer.php
index 29ff3cede..2e4d5f770 100644
--- a/application/views/components/backend_footer.php
+++ b/application/views/components/backend_footer.php
@@ -42,11 +42,11 @@
         </a>
     </div>
 
     <div class="ms-lg-auto">
         <strong id="footer-user-display-name">
-            <?= lang('hello') . ', ' . $user_display_name ?>!
+            <?= lang('hello') . ', ' . e($user_display_name) ?>!
         </strong>
     </div>
 </div>
 
 
diff --git a/application/views/components/google_analytics_script.php b/application/views/components/google_analytics_script.php
index a69b8e890..20f0c9d32 100644
--- a/application/views/components/google_analytics_script.php
+++ b/application/views/components/google_analytics_script.php
@@ -8,20 +8,20 @@
     <script>
         (function(i,s,o,g,r,a,m){i["GoogleAnalyticsObject"]=r;i[r]=i[r]||function(){
             (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
             m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
         })(window,document,"script","//www.google-analytics.com/analytics.js","ga");
-        ga("create", "<?= $google_analytics_code ?>", "auto");
+        ga("create", "<?= e($google_analytics_code) ?>", "auto");
         ga("send", "pageview");
     </script>
 <?php endif ?>
 
 <?php if (substr($google_analytics_code ?? '', 0, 2) === 'G-'): ?>
     <script async src="https://www.googletagmanager.com/gtag/js?id=' . $google_analytics_code . '"></script>
     <script>
         window.dataLayer = window.dataLayer || [];
         function gtag(){dataLayer.push(arguments);}
         gtag("js", new Date());
-        gtag("config", "<?= $google_analytics_code ?>");
+        gtag("config", "<?= e($google_analytics_code) ?>");
     </script>
 <?php endif ?>
 
diff --git a/application/views/components/matomo_analytics_script.php b/application/views/components/matomo_analytics_script.php
index d528c5956..246a21ad2 100644
--- a/application/views/components/matomo_analytics_script.php
+++ b/application/views/components/matomo_analytics_script.php
@@ -11,20 +11,20 @@
         /* tracker methods like "setCustomDimension" should be called before "trackPageView" */
         _paq.push(["setDocumentTitle", document.domain + "/" + document.title]);
         _paq.push(['trackPageView']);
         _paq.push(['enableLinkTracking']);
         (function () {
-            var u = "<?= $matomo_analytics_url ?>";
+            var u = "<?= e($matomo_analytics_url) ?>";
             _paq.push(['setTrackerUrl', u + 'matomo.php']);
             _paq.push(['setSiteId', '1']);
             var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
             g.async = true;
             g.src = u + 'matomo.js';
             s.parentNode.insertBefore(g, s);
         })();
     </script>
 
     <noscript>
-        <p><img src="<?= $matomo_analytics_url ?>matomo.php?idsite=1&amp;rec=1" style="border:0;" alt=""/></p>
+        <p><img src="<?= e($matomo_analytics_url) ?>matomo.php?idsite=1&amp;rec=1" style="border:0;" alt=""/></p>
     </noscript>
 
 <?php endif ?>
diff --git a/application/views/emails/account_recovery_email.php b/application/views/emails/account_recovery_email.php
index 3166ab85b..d962bffcc 100644
--- a/application/views/emails/account_recovery_email.php
+++ b/application/views/emails/account_recovery_email.php
@@ -14,11 +14,11 @@
 <body style="font: 13px arial, helvetica, tahoma;">
 
 <div class="email-container" style="width: 650px; border: 1px solid #eee;">
     <div id="header" style="background-color: #429a82; height: 45px; padding: 10px 15px;">
         <strong id="logo" style="color: white; font-size: 20px; margin-top: 10px; display: inline-block">
-            <?= $settings['company_name'] ?>
+            <?= e($settings['company_name']) ?>
         </strong>
     </div>
 
     <div id="content" style="padding: 10px 15px;">
         <h2>
@@ -35,11 +35,11 @@
         <a href="https://easyappointments.org" style="text-decoration: none;">
             Easy!Appointments
         </a>
         |
         <a href="<?= $settings['company_link'] ?>" style="text-decoration: none;">
-            <?= $settings['company_name'] ?>
+            <?= e($settings['company_name']) ?>
         </a>
     </div>
 </div>
 
 </body>
diff --git a/application/views/emails/appointment_deleted_email.php b/application/views/emails/appointment_deleted_email.php
index 417202ce4..0fc36a03b 100644
--- a/application/views/emails/appointment_deleted_email.php
+++ b/application/views/emails/appointment_deleted_email.php
@@ -19,11 +19,11 @@
 <body style="font: 13px arial, helvetica, tahoma;">
 
 <div class="email-container" style="width: 650px; border: 1px solid #eee;">
     <div id="header" style="background-color: #429a82; height: 45px; padding: 10px 15px;">
         <strong id="logo" style="color: white; font-size: 20px; margin-top: 10px; display: inline-block">
-            <?= $settings['company_name'] ?>
+            <?= e($settings['company_name']) ?>
         </strong>
     </div>
 
     <div id="content" style="padding: 10px 15px;">
         <h2>
@@ -42,19 +42,19 @@
             <tr>
                 <td class="label" style="padding: 3px;font-weight: bold;">
                     <?= lang('service') ?>
                 </td>
                 <td style="padding: 3px;">
-                    <?= $service['name'] ?>
+                    <?= e($service['name']) ?>
                 </td>
             </tr>
             <tr>
                 <td class="label" style="padding: 3px;font-weight: bold;">
                     <?= lang('provider') ?>
                 </td>
                 <td style="padding: 3px;">
-                    <?= $provider['first_name'] . ' ' . $provider['last_name'] ?>
+                    <?= e($provider['first_name'] . ' ' . $provider['last_name']) ?>
                 </td>
             </tr>
             <tr>
                 <td class="label" style="padding: 3px;font-weight: bold;">
                     <?= lang('start') ?>
@@ -85,22 +85,22 @@
                 <tr>
                     <td class="label" style="padding: 3px;font-weight: bold;">
                         <?= lang('location') ?>
                     </td>
                     <td style="padding: 3px;">
-                        <?= $appointment['location'] ?>
+                        <?= e($appointment['location']) ?>
                     </td>
                 </tr>
             <?php endif ?>
 
             <?php if ( ! empty($appointment['notes'])): ?>
                 <tr>
                     <td class="label" style="padding: 3px;font-weight: bold;">
                         <?= lang('notes') ?>
                     </td>
                     <td style="padding: 3px;">
-                        <?= $appointment['notes'] ?>
+                        <?= e($appointment['notes']) ?>
                     </td>
                 </tr>
             <?php endif ?>
         </table>
 
@@ -112,57 +112,57 @@
             <tr>
                 <td class="label" style="padding: 3px;font-weight: bold;">
                     <?= lang('name') ?>
                 </td>
                 <td style="padding: 3px;">
-                    <?= $customer['first_name'] . ' ' . $customer['last_name'] ?>
+                    <?= e($customer['first_name'] . ' ' . $customer['last_name']) ?>
                 </td>
             </tr>
             <tr>
                 <td class="label" style="padding: 3px;font-weight: bold;">
                     <?= lang('email') ?>
                 </td>
                 <td style="padding: 3px;">
-                    <?= $customer['email'] ?>
+                    <?= e($customer['email']) ?>
                 </td>
             </tr>
             <tr>
                 <td class="label" style="padding: 3px;font-weight: bold;">
                     <?= lang('phone_number') ?>
                 </td>
                 <td style="padding: 3px;">
-                    <?= $customer['phone_number'] ?>
+                    <?= e($customer['phone_number']) ?>
                 </td>
             </tr>
             <tr>
                 <td class="label" style="padding: 3px;font-weight: bold;">
                     <?= lang('address') ?>
                 </td>
                 <td style="padding: 3px;">
-                    <?= $customer['address'] ?>
+                    <?= e($customer['address']) ?>
                 </td>
             </tr>
         </table>
 
         <h2>
             <?= lang('reason') ?>
         </h2>
         
         <p>
-            <?= $reason ?>
+            <?= e($reason) ?>
         </p>
     </div>
 
     <div id="footer" style="padding: 10px; text-align: center; margin-top: 10px;
                 border-top: 1px solid #EEE; background: #FAFAFA;">
         Powered by
         <a href="https://easyappointments.org" style="text-decoration: none;">
             Easy!Appointments
         </a>
         |
-        <a href="<?= $settings['company_link'] ?>" style="text-decoration: none;">
-            <?= $settings['company_name'] ?>
+        <a href="<?= e($settings['company_link']) ?>" style="text-decoration: none;">
+            <?= e($settings['company_name']) ?>
         </a>
     </div>
 </div>
 
 </body>
diff --git a/application/views/emails/appointment_saved_email.php b/application/views/emails/appointment_saved_email.php
index 68272a030..58780def7 100644
--- a/application/views/emails/appointment_saved_email.php
+++ b/application/views/emails/appointment_saved_email.php
@@ -23,11 +23,11 @@
 <body style="font: 13px arial, helvetica, tahoma;">
 
 <div class="email-container" style="width: 650px; border: 1px solid #eee;">
     <div id="header" style="background-color: #429a82; height: 45px; padding: 10px 15px;">
         <strong id="logo" style="color: white; font-size: 20px; margin-top: 10px; display: inline-block">
-            <?= $settings['company_name'] ?>
+            <?= e($settings['company_name']) ?>
         </strong>
     </div>
 
     <div id="content" style="padding: 10px 15px;">
         <h2>
@@ -46,19 +46,19 @@
             <tr>
                 <td class="label" style="padding: 3px;font-weight: bold;">
                     <?= lang('service') ?>
                 </td>
                 <td style="padding: 3px;">
-                    <?= $service['name'] ?>
+                    <?= e($service['name']) ?>
                 </td>
             </tr>
             <tr>
                 <td class="label" style="padding: 3px;font-weight: bold;">
                     <?= lang('provider') ?>
                 </td>
                 <td style="padding: 3px;">
-                    <?= $provider['first_name'] . ' ' . $provider['last_name'] ?>
+                    <?= e($provider['first_name'] . ' ' . $provider['last_name']) ?>
                 </td>
             </tr>
             <tr>
                 <td class="label" style="padding: 3px;font-weight: bold;">
                     <?= lang('start') ?>
@@ -89,22 +89,22 @@
                 <tr>
                     <td class="label" style="padding: 3px;font-weight: bold;">
                         <?= lang('location') ?>
                     </td>
                     <td style="padding: 3px;">
-                        <?= $appointment['location'] ?>
+                        <?= e($appointment['location']) ?>
                     </td>
                 </tr>
             <?php endif ?>
 
             <?php if ( ! empty($appointment['notes'])): ?>
                 <tr>
                     <td class="label" style="padding: 3px;font-weight: bold;">
                         <?= lang('notes') ?>
                     </td>
                     <td style="padding: 3px;">
-                        <?= $appointment['notes'] ?>
+                        <?= e($appointment['notes']) ?>
                     </td>
                 </tr>
             <?php endif ?>
         </table>
 
@@ -116,57 +116,57 @@
             <tr>
                 <td class="label" style="padding: 3px;font-weight: bold;">
                     <?= lang('name') ?>
                 </td>
                 <td style="padding: 3px;">
-                    <?= $customer['first_name'] . ' ' . $customer['last_name'] ?>
+                    <?= e($customer['first_name'] . ' ' . $customer['last_name']) ?>
                 </td>
             </tr>
             <tr>
                 <td class="label" style="padding: 3px;font-weight: bold;">
                     <?= lang('email') ?>
                 </td>
                 <td style="padding: 3px;">
-                    <?= $customer['email'] ?>
+                    <?= e($customer['email']) ?>
                 </td>
             </tr>
             <tr>
                 <td class="label" style="padding: 3px;font-weight: bold;">
                     <?= lang('phone_number') ?>
                 </td>
                 <td style="padding: 3px;">
-                    <?= $customer['phone_number'] ?>
+                    <?= e($customer['phone_number']) ?>
                 </td>
             </tr>
             <tr>
                 <td class="label" style="padding: 3px;font-weight: bold;">
                     <?= lang('address') ?>
                 </td>
                 <td style="padding: 3px;">
-                    <?= $customer['address'] ?>
+                    <?= e($customer['address']) ?>
                 </td>
             </tr>
         </table>
 
         <h2>
             <?= lang('appointment_link_title') ?>
         </h2>
 
-        <a href="<?= $appointment_link ?>" style="width: 600px;">
-            <?= $appointment_link ?>
+        <a href="<?= e($appointment_link) ?>" style="width: 600px;">
+            <?= e($appointment_link) ?>
         </a>
     </div>
 
     <div id="footer" style="padding: 10px; text-align: center; margin-top: 10px;
                 border-top: 1px solid #EEE; background: #FAFAFA;">
         Powered by
         <a href="https://easyappointments.org" style="text-decoration: none;">
             Easy!Appointments
         </a>
         |
-        <a href="<?= $settings['company_link'] ?>" style="text-decoration: none;">
-            <?= $settings['company_name'] ?>
+        <a href="<?= e($settings['company_link']) ?>" style="text-decoration: none;">
+            <?= e($settings['company_name']) ?>
         </a>
     </div>
 </div>
 
 </body>

Vulnerable code:                                                     ? $group[0]['category_name']
                                                            . $service['name'] . '</option>';
                                                    . $service['name'] . '</option>';
                                            <option value="<?= $appointment_status_option ?>">
                                                <?= $appointment_status_option ?>
            <?= lang('hello') . ', ' . $user_display_name ?>!
        ga("create", "<?= $google_analytics_code ?>", "auto");
        gtag("config", "<?= $google_analytics_code ?>");
            var u = "<?= $matomo_analytics_url ?>";
        <p><img src="<?= $matomo_analytics_url ?>matomo.php?idsite=1&amp;rec=1" style="border:0;" alt=""/></p>
            <?= $settings['company_name'] ?>
            <?= $settings['company_name'] ?>
            <?= $settings['company_name'] ?>
                    <?= $service['name'] ?>
                    <?= $provider['first_name'] . ' ' . $provider['last_name'] ?>
                        <?= $appointment['location'] ?>
                        <?= $appointment['notes'] ?>
                    <?= $customer['first_name'] . ' ' . $customer['last_name'] ?>
                    <?= $customer['email'] ?>
                    <?= $customer['phone_number'] ?>
                    <?= $customer['address'] ?>
            <?= $reason ?>
        <a href="<?= $settings['company_link'] ?>" style="text-decoration: none;">
            <?= $settings['company_name'] ?>
            <?= $settings['company_name'] ?>
                    <?= $service['name'] ?>
                    <?= $provider['first_name'] . ' ' . $provider['last_name'] ?>
                        <?= $appointment['location'] ?>
                        <?= $appointment['notes'] ?>
                    <?= $customer['first_name'] . ' ' . $customer['last_name'] ?>
                    <?= $customer['email'] ?>
                    <?= $customer['phone_number'] ?>
                    <?= $customer['address'] ?>
        <a href="<?= $appointment_link ?>" style="width: 600px;">
            <?= $appointment_link ?>
        <a href="<?= $settings['company_link'] ?>" style="text-decoration: none;">
            <?= $settings['company_name'] ?>
Fixed code:                                         
                                            
                                                    ? e($group[0]['category_name'])
                                                            . e($service['name']) . '</option>';
                                                    . e($service['name']) . '</option>';
                                            <option value="<?= e($appointment_status_option) ?>">
                                                <?= e($appointment_status_option) ?>
            <?= lang('hello') . ', ' . e($user_display_name) ?>!
        ga("create", "<?= e($google_analytics_code) ?>", "auto");
        gtag("config", "<?= e($google_analytics_code) ?>");
            var u = "<?= e($matomo_analytics_url) ?>";
        <p><img src="<?= e($matomo_analytics_url) ?>matomo.php?idsite=1&amp;rec=1" style="border:0;" alt=""/></p>
            <?= e($settings['company_name']) ?>
            <?= e($settings['company_name']) ?>
            <?= e($settings['company_name']) ?>
                    <?= e($service['name']) ?>
                    <?= e($provider['first_name'] . ' ' . $provider['last_name']) ?>
                        <?= e($appointment['location']) ?>
                        <?= e($appointment['notes']) ?>
                    <?= e($customer['first_name'] . ' ' . $customer['last_name']) ?>
                    <?= e($customer['email']) ?>
                    <?= e($customer['phone_number']) ?>
                    <?= e($customer['address']) ?>
            <?= e($reason) ?>
        <a href="<?= e($settings['company_link']) ?>" style="text-decoration: none;">
            <?= e($settings['company_name']) ?>
            <?= e($settings['company_name']) ?>
                    <?= e($service['name']) ?>
                    <?= e($provider['first_name'] . ' ' . $provider['last_name']) ?>
                        <?= e($appointment['location']) ?>
                        <?= e($appointment['notes']) ?>
                    <?= e($customer['first_name'] . ' ' . $customer['last_name']) ?>
                    <?= e($customer['email']) ?>
                    <?= e($customer['phone_number']) ?>
                    <?= e($customer['address']) ?>
        <a href="<?= e($appointment_link) ?>" style="width: 600px;">
            <?= e($appointment_link) ?>
        <a href="<?= e($settings['company_link']) ?>" style="text-decoration: none;">
            <?= e($settings['company_name']) ?>