CVE-2025-29448
Description
Booking logic flaw in Easy!Appointments v1.5.1 allows unauthenticated attackers to create appointments with excessively long durations, causing a denial of service by blocking all future booking availability.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Easy!Appointments v1.5.1 allows unauthenticated attackers to create excessively long appointments, blocking all future availability and causing denial of service.
Vulnerability
Overview
CVE-2025-29448 is a booking logic flaw in Easy!Appointments v1.5.1 that allows unauthenticated attackers to create appointments with excessively long durations, thereby blocking all future booking availability and causing a denial of service (DoS). The root cause is that the application does not validate the end_datetime parameter submitted by the client; instead, it trusts the value provided without recalculating it from the selected service's duration [2].
Exploitation
An attacker can exploit this vulnerability by intercepting an appointment booking request and modifying the post_data[appointment][end_datetime] parameter to a date far in the future. The application accepts the manipulated booking without re-calculating the end time based on the actual service duration, effectively creating a highly extended booked time slot [4]. No authentication is required, and the attack can be performed by any unauthenticated user via the public booking interface.
Impact
Successful exploitation results in a denial of service: the fake appointment occupies a provider's calendar for an extended (or indefinite) period, making the provider unavailable for legitimate bookings. This can render the scheduling system unusable until the fictitious appointment is manually removed by an administrator [1]. The impact is limited to availability, but it can be disruptive for businesses that rely on the scheduler.
Mitigation
The vulnerability has been fixed in commit 74633b60f28bdef3cc9f905c0599cef121fee32b, which ensures that the appointment's end_datetime is always calculated server-side from the selected service's duration rather than accepting the client-provided value [2]. Users should update to the latest version of Easy!Appointments or apply the patch to prevent exploitation. The vendor's official repository contains the fix, and the application can be self-hosted [3].
- NVD - CVE-2025-29448
- Make sure the end time is defined based on the selected service duration · alextselegidis/easyappointments@74633b6
- GitHub - alextselegidis/easyappointments: :date: Easy!Appointments - Self Hosted Appointment Scheduler
- GitHub - Abdullah4eb/CVE-2025-29448: unauthenticated booking logic flaw in Easy!Appointments v1.5.1 causing denial of service.
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
alextselegidis/easyappointmentsPackagist | <= 1.5.1 | — |
Affected products
3- Easy!Appointments/Easy!Appointmentsdescription
- Range: = 1.5.1
Patches
174633b60f28bMake sure the end time is defined based on the selected service duration
3 files changed · +24 −22
application/controllers/api/v1/Appointments_api_v1.php+1 −21 modified@@ -216,7 +216,7 @@ public function store(): void } if (!array_key_exists('end_datetime', $appointment)) { - $appointment['end_datetime'] = $this->calculate_end_datetime($appointment); + $appointment['end_datetime'] = $this->appointments_model->calculate_end_datetime($appointment); } $appointment_id = $this->appointments_model->save($appointment); @@ -233,26 +233,6 @@ public function store(): void } } - /** - * Calculate the end date time of an appointment based on the selected service. - * - * @param array $appointment Appointment data. - * - * @return string Returns the end date time value. - * - * @throws Exception - */ - private function calculate_end_datetime(array $appointment): string - { - $duration = $this->services_model->value($appointment['id_services'], 'duration'); - - $end = new DateTime($appointment['start_datetime']); - - $end->add(new DateInterval('PT' . $duration . 'M')); - - return $end->format('Y-m-d H:i:s'); - } - /** * Send the required notifications and trigger syncing after saving an appointment. *
application/controllers/Booking.php+3 −1 modified@@ -441,6 +441,7 @@ public function register(): void $appointment_status_options_json = setting('appointment_status_options', '[]'); $appointment_status_options = json_decode($appointment_status_options_json, true) ?? []; $appointment['status'] = $appointment_status_options[0] ?? null; + $appointment['end_datetime'] = $this->appointments_model->calculate_end_datetime($appointment); $this->appointments_model->only($appointment, $this->allowed_appointment_fields); @@ -453,7 +454,8 @@ public function register(): void 'company_name' => setting('company_name'), 'company_link' => setting('company_link'), 'company_email' => setting('company_email'), - 'company_color' => !empty($company_color) && $company_color != DEFAULT_COMPANY_COLOR ? $company_color : null, + 'company_color' => + !empty($company_color) && $company_color != DEFAULT_COMPANY_COLOR ? $company_color : null, 'date_format' => setting('date_format'), 'time_format' => setting('time_format'), ];
application/models/Appointments_model.php+20 −0 modified@@ -646,4 +646,24 @@ public function api_decode(array &$appointment, ?array $base = null): void $appointment = $decoded_request; } + + /** + * Calculate the end date time of an appointment based on the selected service. + * + * @param array $appointment Appointment data. + * + * @return string Returns the end date time value. + * + * @throws Exception + */ + public function calculate_end_datetime(array $appointment): string + { + $duration = $this->db->get_where('services', ['id' => $appointment['id_services']])?->row()?->duration; + + $end_date_time_object = new DateTime($appointment['start_datetime']); + + $end_date_time_object->add(new DateInterval('PT' . $duration . 'M')); + + return $end_date_time_object->format('Y-m-d H:i:s'); + } }
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
3News mentions
0No linked articles in our index yet.