Advisories for Composer/Alextselegidis/Easyappointments package

2026

Easy!Appointments: Authorization bypass in Google OAuth provider binding lets any backend user rebind a peer provider's Google sync

Google::oauth at application/controllers/Google.php:278 stores its URL-supplied provider_id in the session, and oauth_callback saves the issued Google OAuth token against that row without checking the caller owns the provider. Any logged-in backend user (admin, provider, or secretary) rebinds a peer provider's Google sync to a Google account they control. The peer's appointments then sync into the attacker's calendar with each customer's name and email attached as attendee data.

Easy!Appointments has unauthenticated customer PII disclosure on booking reschedule page

The booking reschedule view at /index.php/booking/reschedule/{appointment_hash} (handled by Booking::index()) embeds the entire customer record as inline JavaScript (const vars = {… "customer_data": {…}, …}) without authentication and without field whitelisting. Anyone in possession of the 12-character appointment_hash — which appears in plain text in reschedule emails, confirmation page URLs, and operator-side calendar links — can read every column of that customer's row in the ea_users table. Verified against v1.5.2 with …

Easy!Appointments has server-side request forgery in CalDAV connection test that exposes the deployment's internal network

Caldav::connect_to_server at application/controllers/Caldav.php:60 hands the request's caldav_url to a Guzzle REPORT call without scheme or host validation. A logged-in backend user (admin, provider, or secretary) reaches loopback, RFC1918, and link-local hosts on the deployment's network. The Guzzle exception path returns the upstream status code plus ~120 bytes of response body in the JSON message field (Caldav.php:74-78), so the SSRF is semi-blind.

Easy!Appointments disable_booking_message rendered as raw HTML on public booking page — Stored XSS

Easy!Appointments allows administrators to define a custom "booking disabled" message through the booking settings page. That value is stored in the disable_booking_message setting via a rich-text editor and later passed directly to the public booking_message view without escaping or sanitization: <p><?= vars('message_text') ?></p> An authenticated administrator can store HTML or JavaScript in this field, enable disabled-booking mode, and trigger stored XSS in every unauthenticated visitor who opens the public booking …

Easy!Appointments appointments/store and appointments/update allow cross-provider appointment injection — Authorization Bypass

Easy!Appointments correctly filters provider-scoped appointments in the appointments/search response, proving that provider isolation is an intended security boundary. However, the direct mutation endpoints appointments/store and appointments/update only check generic appointment privileges and never verify that the submitted id_users_provider belongs to the current session. A normal authenticated provider can inject new appointments into another provider's schedule via store, or reassign existing appointments into a foreign provider's calendar via update. The store …

alextselegidis/easyappointments is Vulnerable to CSRF Protection Bypass

application/core/EA_Security.php::csrf_verify() only enforces CSRF for POST requests and returns early for non-POST methods. Several application endpoints perform state-changing operations while accepting parameters from GET (or $_REQUEST), so an attacker can perform CSRF by forcing a victim's browser to issue a crafted GET request. Impact: creation of admin accounts, modification of admin email/password, and full admin account takeover

2025
2023
2022