How CVE-2026-92799 Overwrites Bookly Customer Records
Bookly exposes its booking wizard through admin-ajax.php actions that require no login and no nonce: the controller registers bookly_session_save and bookly_save_appointment as wp_ajax_nopriv_ handlers and overrides csrfTokenValid() to return true. Its ownership check should stop a stranger from changing an existing customer record. In 28.2 that check compares the submitted verification_code against the six-digit code stored in the attacker's own session using a loose '!='. The json_data channel json_decode()s input and wp_kses() filters only strings, so a non-string JSON value passes through and PHP evaluates it as equal to any non-zero code. The gate never fires. saveAppointment() loads the victim's record via Customer::loadBy() on the attacker-chosen phone or email, and UserBookingData::save() overwrites its name, email, phone, birthday, and address.
BitFire FREE Bot Protection Stops the Automated Delivery
The entire attack is automated: scripted requests to /wp-admin/admin-ajax.php with the bookly_session_save and bookly_save_appointment actions, no login, no nonce. That is exactly the traffic BitFire FREE Bot Protection stops. Before WordPress or Bookly runs any code, Bot Protection classifies the request: unknown or restricted automation is limited to safe viewing and cannot call sensitive AJAX endpoints, submit forms, or POST exploit data, and clients presenting as browsers must pass lightweight JavaScript verification that real browsers normally pass automatically and scripted exploit clients fail. Known tools such as WPScan and nikto are blocked outright. A bot that cannot reach bookly_save_appointment never reaches the flawed comparison, and the customer record is never touched. This request-layer protection ships with BitFire FREE for eligible non-commercial sites; commercial sites need the matching commercial license.
BitFire PRO RASP Blocks the Unauthorized Database Write
If any request slips past the request layer — including a manually driven browser — BitFire PRO RASP enforces authorization at the protected operation itself. UserBookingData::save() is not WordPress core and not an approved membership or commerce plugin, so RASP treats its write of another person's bookly_customers row as exactly what it is: a non-admin account-record change with no legitimate authority behind it. The database protection guard blocks the unauthorized update before it persists, and the attacker's chosen name, email, phone, birthday, and address never reach the victim's record. RASP does not sanitize input and does not need to recognize CVE-2026-92799; it simply refuses the dangerous runtime outcome.
Patch to Bookly 28.3 and Verify Your Version
Update Bookly to 28.3 or later immediately. The fix replaces both loose comparisons with verificationCodeMatches(), which casts integers to strings, rejects any non-string submitted value, requires a digit-only code, and compares with hash_equals(). Version 28.3 also binds acceptance to the recipient the code was actually sent to, invalidates the stored code after five wrong entries, and gates record rewrites behind customerIdentityConfirmed() in UserBookingData::save(), so a matched record's filled fields are overwritten only when the session proves ownership. Admins should verify the installed version in main.php — 28.2 or lower is vulnerable. The endpoint itself remains nopriv-registered and CSRF-unchecked in 28.3, which is precisely why layered controls like Bot Protection and RASP matter even on patched sites.
If Your Site Was Affected, Investigate for Persistence
Patching closes the verification bypass; it does not undo an overwrite that already happened. If your site ran Bookly 28.2 or earlier, assume the exposure was live and investigate. Look for customer records whose contact details changed without a matching booking, check Bookly's notification routing, and rotate credentials for any account whose recovery email or phone points at attacker-controlled addresses. Run BitFire Threat Hunter for a thorough post-compromise sweep: it hunts backdoor WordPress administrator accounts, hidden database triggers, long-running PHP processes, and droppers that can restore malware or reinfect the site. This CVE does not grant code execution, but a site scanned by the same automation often carries other persistence. Remove what Threat Hunter finds and rotate the relevant credentials.
Stop the Next Exploit with BitFire
CVE-2026-92799 shows how one loose comparison turns a routine booking form into a customer-data tampering tool. BitFire stops this attack twice: BitFire FREE Bot Protection rejects the automated AJAX delivery before WordPress executes a single line of Bookly code, and BitFire PRO RASP blocks the unauthorized customer-record write at the database itself. Install Bookly 28.3 today, run Threat Hunter if 28.2 ever touched your site, and deploy BitFire to keep the next unauthenticated exploit from getting that far. Get BitFire FREE now and put layered protection in front of every request.