CVE-2026-108758 Overview
CVE-2026-108758 is an authorization bypass vulnerability in Easy!Appointments through version 1.6.0. The flaw resides in the Booking::register() controller method, which fails to verify ownership of an appointment before applying updates. Unauthenticated attackers can supply an appointment id along with a self-asserted manage_mode flag to modify any appointment without providing the required appointment_hash. By enumerating sequential appointment identifiers, attackers can rewrite appointment details, rebind bookings to attacker-controlled customers, and retrieve management hashes used for rescheduling or cancellation. The weakness is categorized under CWE-639: Authorization Bypass Through User-Controlled Key.
Critical Impact
Unauthenticated attackers can take over arbitrary appointments, exfiltrate booking metadata, and hijack management hashes to modify or cancel any scheduled appointment.
Affected Products
- Easy!Appointments versions up to and including 1.6.0
- The application/controllers/Booking.php controller (Booking::register() endpoint)
- Deployments exposing the public booking endpoint to the internet
Discovery Timeline
- 2026-10-11 - CVE-2026-108758 published to NVD
- 2026-10-16 - Last updated in NVD database
Technical Details for CVE-2026-108758
Vulnerability Analysis
The Booking::register() endpoint in Easy!Appointments accepts a POST body containing appointment data, customer data, and a manage_mode boolean. When manage_mode is true, the controller treats the request as an update to an existing appointment identified by appointment['id']. The pre-patch logic does not validate that the caller possesses the appointment's secret hash before performing the update. Any unauthenticated client can set manage_mode=true, specify an arbitrary numeric id, and overwrite the targeted record. Because appointment identifiers are sequential integers, an attacker can enumerate the full appointment inventory and operate on every record. The server response returns the management hash associated with the modified appointment, enabling further manipulation through the standard customer-facing reschedule and cancel flows.
Root Cause
The root cause is a missing authorization check that binds the submitted appointment id to the caller's possession of the record's hash. The controller trusts the client-supplied manage_mode flag as sufficient authority to execute an update. This matches the [CWE-639] pattern where a user-controlled key is accepted without verifying that the requester is authorized to act on the referenced object.
Attack Vector
The attack is unauthenticated and network-based against the publicly reachable /index.php/booking/register endpoint. An attacker iterates through appointment identifiers starting from 1, posts crafted JSON that overwrites customer bindings and appointment metadata, and captures the returned hash for each record. No user interaction, prior credentials, or privileged access is required.
$customer = $post_data['customer'] ?? [];
$manage_mode = filter_var($post_data['manage_mode'] ?? false, FILTER_VALIDATE_BOOLEAN);
+ // Security: Verify hash when updating an existing appointment
+ if ($manage_mode && !empty($appointment['id'])) {
+ $appointment_hash = $post_data['appointment_hash'] ?? '';
+
+ if (empty($appointment_hash)) {
+ throw new RuntimeException('Appointment hash is required for updates.');
+ }
+
+ // Verify the hash matches the appointment being updated
+ $existing_appointments = $this->appointments_model->get([
+ 'id' => $appointment['id'],
+ 'hash' => $appointment_hash
+ ]);
+
+ if (empty($existing_appointments)) {
+ throw new RuntimeException('Invalid appointment hash or appointment not found.');
+ }
+ }
+
// Validate required appointment fields
if (empty($appointment) || !is_array($appointment)) {
throw new InvalidArgumentException('Invalid appointment data.');
Source: GitHub Commit: Authorization Fix
The patch enforces that any update request supplies a valid appointment_hash matching the stored record before the controller proceeds.
Detect Identity Attacks the Moment Authentication Fails
Singularity™ Identity surfaces credential misuse, lateral movement, and privilege escalation in real time, so you can contain the breach before it spreads.
Stop Identity AttacksDetection Methods for CVE-2026-108758
Indicators of Compromise
- POST requests to /index.php/booking/register containing manage_mode=true without a corresponding valid appointment_hash field.
- Sequential enumeration patterns in web access logs targeting booking endpoints with incrementing appointment[id] values.
- Unexpected changes to appointment customer bindings, times, or notes with no matching administrator activity in audit logs.
- Spikes in HTTP 200 responses from Booking::register() originating from a single source IP within short time windows.
Detection Strategies
- Inspect web server and application logs for POST bodies to the booking register endpoint that include manage_mode without the client first retrieving the appointment via a legitimate management link.
- Correlate database audit records for the ea_appointments table to identify UPDATE operations originating from unauthenticated sessions.
- Deploy a WAF signature that blocks requests to booking/register when manage_mode=true is present but no appointment_hash parameter accompanies it.
Monitoring Recommendations
- Alert on a single client IP generating more than a threshold number of booking/register POSTs per minute.
- Monitor outbound responses from the booking endpoint for payloads containing hash fields to detect mass hash exfiltration.
- Baseline normal appointment modification volumes and alert on deviations outside business hours.
How to Mitigate CVE-2026-108758
Immediate Actions Required
- Apply the upstream fix from commit 09c6fb30 or upgrade to a release that incorporates it.
- Rotate all appointment hashes after patching so previously exfiltrated hashes cannot be reused.
- Review the ea_appointments table for unexpected customer rebindings, time changes, or new entries created during the exposure window.
Patch Information
The maintainers of Easy!Appointments resolved the issue in commit 09c6fb30b6aac0830a820d6bec3d2eb241daf150, which modifies application/controllers/Booking.php to require a valid appointment_hash whenever manage_mode is set and an existing appointment id is referenced. See the VulnCheck Advisory: Authorization Bypass and the HackMD Appointment Takeover Analysis for additional technical context.
Workarounds
- Restrict access to /index.php/booking/register using network ACLs or authentication at the reverse proxy layer until the patch can be deployed.
- Deploy a WAF rule that rejects any POST to booking/register where manage_mode=true is present without a non-empty appointment_hash.
- Temporarily disable public self-service booking if the deployment supports administrator-only scheduling.
# Example NGINX rule rejecting manage_mode updates without an appointment_hash
location = /index.php/booking/register {
if ($request_method = POST) {
set $flag "";
if ($request_body ~* "manage_mode\"?\s*[:=]\s*true") { set $flag "M"; }
if ($request_body !~* "appointment_hash\"?\s*[:=]\s*\"[A-Za-z0-9]+\"") { set $flag "${flag}H"; }
if ($flag = "MH") { return 403; }
}
include fastcgi_params;
fastcgi_pass php-fpm;
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

