CVE-2023-3568 (published 2023-07-10T16:15Z)

Open Redirect in GitHub repository alextselegidis/easyappointments prior to 1.5.0.\n\n

CVSS v3 base score: 4.8, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N)

Weakness information:
cwe_id: CWE-601
cwe_name: URL Redirection to Untrusted Site ('Open Redirect')
description: A web application accepts a user-controlled input that specifies a link to an external site, and uses that link in a Redirect. This simplifies phishing attacks.
extended_description: An http parameter may contain a URL value and could cause the web application to redirect the request to the specified URL. By modifying the URL value to a malicious site, an attacker may successfully launch a phishing scam and steal user credentials. Because the server name in the modified link is identical to the original site, phishing attempts have a more trustworthy appearance. Whether this issue poses a vulnerability will be subject to the intended behavior of the application. For example, a search engine might intentionally provide redirects to arbitrary URLs.
         

Fix information:
repo_url: https://github.com/alextselegidis/easyappointments
commit_details: repo_url: https://github.com/alextselegidis/easyappointments
author: Alex Tselegidis
author_date: 2023-07-17 08:14:04+02:00
msg: Only allow authorized users to manage appointments from the calendar page (#1387)
repository: repo_url: https://github.com/alextselegidis/easyappointments
repo_name: alextselegidis/easyappointments
description: :date: Easy!Appointments - Self Hosted Appointment Scheduler
repo_language: PHP
owner: alextselegidis
file_changes: filename: Calendar.php
change_type: ModificationType.MODIFY
diff: @@ -181,9 +181,12 @@ class Calendar extends EA_Controller {
     {
         try
         {
-            // Save customer changes to the database.
             $customer_data = request('customer_data');
+            $appointment_data = request('appointment_data');
+
+            $this->check_event_permissions($appointment_data['id_users_provider']);
 
+            // Save customer changes to the database.
             if ($customer_data)
             {
                 $customer = $customer_data;
@@ -216,8 +219,6 @@ class Calendar extends EA_Controller {
             }
 
             // Save appointment changes to the database.
-            $appointment_data = request('appointment_data');
-
             $manage_mode = ! empty($appointment_data['id']);
 
             if ($appointment_data)
@@ -323,6 +324,9 @@ class Calendar extends EA_Controller {
 
             // Store appointment data for later use in this method.
             $appointment = $this->appointments_model->find($appointment_id);
+
+            $this->check_event_permissions($appointment['id_users_provider']);
+
             $provider = $this->providers_model->find($appointment['id_users_provider'], TRUE);
             $customer = $this->customers_model->find($appointment['id_users_customer'], TRUE);
             $service = $this->services_model->find($appointment['id_services'], TRUE);
@@ -373,7 +377,11 @@ class Calendar extends EA_Controller {
                 throw new RuntimeException('You do not have the required permissions for this task.');
             }
 
-            $provider = $this->providers_model->find($unavailability['id_users_provider']);
+            $provider_id = $unavailability['id_users_provider'];
+
+            $this->check_event_permissions($provider_id);
+
+            $provider = $this->providers_model->find($provider_id);
 
             $unavailability_id = $this->unavailabilities_model->save($unavailability);
 
@@ -409,6 +417,8 @@ class Calendar extends EA_Controller {
             $unavailability_id = request('unavailability_id');
 
             $unavailability = $this->appointments_model->find($unavailability_id);
+            
+            $this->check_event_permissions($unavailability['id_users_provider']);
 
             $provider = $this->providers_model->find($unavailability['id_users_provider']);
 
@@ -742,4 +752,20 @@ class Calendar extends EA_Controller {
             json_exception($e);
         }
     }
+
+    private function check_event_permissions($provider_id)
+    {
+        $user_id = (int)session('user_id');
+        $role_slug = session('role_slug');
+
+        if ($role_slug === DB_SLUG_SECRETARY && ! $this->secretaries_model->is_provider_supported($user_id, $provider_id))
+        {
+            abort(403);
+        }
+
+        if ($role_slug === DB_SLUG_PROVIDER && $user_id !== $provider_id)
+        {
+            abort(403);
+        }
+    }
 }

programming_language: PHP