CVE-2023-2104: Improper Access Control (CWE-284)
value: Improper Access Control in GitHub repository alextselegidis/easyappointments prior to 1.5.0.
CWE description: The product does not restrict or incorrectly restricts access to a resource from an unauthorized actor.
CVSS v3 base score: 5.4
Published: 2023-04-15T14:15Z
Repository: https://github.com/alextselegidis/easyappointments
Language: PHP
Files changed: application/controllers/Calendar.php
Commit date: 2023-04-15 14:39:12 +0200
Commit message: Do not return appointments of a different user to the another provider or secretary on the default calendar screen.

Diff: diff --git a/application/controllers/Calendar.php b/application/controllers/Calendar.php
index f130a4623..694631c2d 100644
--- a/application/controllers/Calendar.php
+++ b/application/controllers/Calendar.php
@@ -669,10 +669,66 @@ class Calendar extends EA_Controller {
             foreach ($response['unavailabilities'] as &$unavailability)
             {
                 $unavailability['provider'] = $this->providers_model->find($unavailability['id_users_provider']);
             }
 
+            unset($appointment);
+
+            $user_id = session('user_id');
+
+            $role_slug = session('role_slug');
+
+            // If the current user is a provider he must only see his own appointments.
+            if ($role_slug === DB_SLUG_PROVIDER)
+            {
+                foreach ($response['appointments'] as $index => $appointment)
+                {
+                    if ((int)$appointment['id_users_provider'] !== (int)$user_id)
+                    {
+                        unset($response['appointments'][$index]);
+                    }
+                }
+
+                $response['appointments'] = array_values($response['appointments']);
+
+                foreach ($response['unavailabilities'] as $index => $unavailability)
+                {
+                    if ((int)$unavailability['id_users_provider'] !== (int)$user_id)
+                    {
+                        unset($response['unavailabilities'][$index]);
+                    }
+                }
+
+                $response['unavailabilities'] = array_values($response['unavailabilities']);
+            }
+
+            // If the current user is a secretary he must only see the appointments of his providers.
+            if ($role_slug === DB_SLUG_SECRETARY)
+            {
+                $providers = $this->secretaries_model->find($user_id)['providers'];
+
+                foreach ($response['appointments'] as $index => $appointment)
+                {
+                    if ( ! in_array((int)$appointment['id_users_provider'], $providers))
+                    {
+                        unset($response['appointments'][$index]);
+                    }
+                }
+
+                $response['appointments'] = array_values($response['appointments']);
+
+                foreach ($response['unavailabilities'] as $index => $unavailability)
+                {
+                    if ( ! in_array((int)$unavailability['id_users_provider'], $providers))
+                    {
+                        unset($response['unavailabilities'][$index]);
+                    }
+                }
+
+                $response['unavailabilities'] = array_values($response['unavailabilities']);
+            }
+
             json_response($response);
         }
         catch (Throwable $e)
         {
             json_exception($e);

Fixed code:             unset($appointment);

            $user_id = session('user_id');

            $role_slug = session('role_slug');

            // If the current user is a provider he must only see his own appointments.
            if ($role_slug === DB_SLUG_PROVIDER)
            {
                foreach ($response['appointments'] as $index => $appointment)
                {
                    if ((int)$appointment['id_users_provider'] !== (int)$user_id)
                    {
                        unset($response['appointments'][$index]);
                    }
                }

                $response['appointments'] = array_values($response['appointments']);

                foreach ($response['unavailabilities'] as $index => $unavailability)
                {
                    if ((int)$unavailability['id_users_provider'] !== (int)$user_id)
                    {
                        unset($response['unavailabilities'][$index]);
                    }
                }

                $response['unavailabilities'] = array_values($response['unavailabilities']);
            }

            // If the current user is a secretary he must only see the appointments of his providers.
            if ($role_slug === DB_SLUG_SECRETARY)
            {
                $providers = $this->secretaries_model->find($user_id)['providers'];

                foreach ($response['appointments'] as $index => $appointment)
                {
                    if ( ! in_array((int)$appointment['id_users_provider'], $providers))
                    {
                        unset($response['appointments'][$index]);
                    }
                }

                $response['appointments'] = array_values($response['appointments']);

                foreach ($response['unavailabilities'] as $index => $unavailability)
                {
                    if ( ! in_array((int)$unavailability['id_users_provider'], $providers))
                    {
                        unset($response['unavailabilities'][$index]);
                    }
                }

                $response['unavailabilities'] = array_values($response['unavailabilities']);
            }