CVE-2025-14982

Booking Calendar <= 10.14.11 - Missing Authorization to Sensitive Information Exposure

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
10.14.12
Patched in
1d
Time to patch

Description

The Booking Calendar plugin for WordPress is vulnerable to Missing Authorization leading to Sensitive Information Exposure in all versions up to, and including, 10.14.11. This makes it possible for authenticated attackers, with Subscriber-level access and above, to view all booking records in the database, including personally identifiable information (PII) such as names, email addresses, phone numbers, physical addresses, payment status, booking costs, and booking hashes belonging to other users.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=10.14.11
PublishedJanuary 15, 2026
Last updatedJanuary 16, 2026
Affected pluginbooking

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2025-14982 ## 1. Vulnerability Summary The **Booking Calendar** plugin (versions <= 10.14.11) contains a **Missing Authorization** vulnerability in its AJAX handling logic. Specifically, the plugin registers an AJAX action that retrieves detailed booking records f…

Show full research plan

Exploitation Research Plan - CVE-2025-14982

1. Vulnerability Summary

The Booking Calendar plugin (versions <= 10.14.11) contains a Missing Authorization vulnerability in its AJAX handling logic. Specifically, the plugin registers an AJAX action that retrieves detailed booking records from the database but fails to verify that the requesting user has the appropriate capabilities (e.g., manage_bookings or manage_options). This allows any authenticated user, including those with Subscriber privileges, to access full booking details, including Personally Identifiable Information (PII) such as names, email addresses, phone numbers, and payment status of other users.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: WPBC_AJAX_GET_BOOKINGS_DATA (or wpbc_get_bookings depending on the exact internal dispatching)
  • HTTP Method: POST
  • Authentication: Required (Subscriber or higher)
  • Parameters:
    • action: WPBC_AJAX_GET_BOOKINGS_DATA
    • nonce: A valid WordPress nonce for the action (localized as wpbc_nonce or wpbc_ajax_nonce).
    • search_params: Often a URL-encoded string or object containing query parameters like limit, offset, or booking_type.
  • Preconditions: At least one booking must exist in the system (from any user).

3. Code Flow

  1. Registration: The plugin registers the AJAX hook in booking/core/wpbc-ajax.php or booking/core/admin/wpbc-admin-ajax.php.
    • add_action( 'wp_ajax_WPBC_AJAX_GET_BOOKINGS_DATA', 'wpbc_ajax_get_bookings_data_handler' );
  2. Missing Capability Check: The handler function wpbc_ajax_get_bookings_data_handler (or similar) checks for a valid nonce using check_ajax_referer() or wp_verify_nonce(), but fails to call current_user_can().
  3. Data Retrieval: The code calls wpbc_get_bookings_objects() or a direct $wpdb query to fetch rows from the wp_booking and wp_booking_data tables.
  4. Sink: The retrieved data is returned to the user via wp_send_json_success() or echo json_encode().

4. Nonce Acquisition Strategy

The plugin localizes the nonce in the admin dashboard for all logged-in users. Even a Subscriber can access the /wp-admin/ dashboard.

  1. Step 1: Log in as a Subscriber.
  2. Step 2: Navigate to the /wp-admin/index.php page.
  3. Step 3: Use browser_eval to extract the nonce from the global JavaScript object localized by the plugin.
    • The plugin typically uses the identifier wpbc_global_settings.
    • Command: browser_eval("window.wpbc_global_settings?.wpbc_ajax_nonce") or browser_eval("window.wpbc_ajax_nonce").
  4. Validation: If the localized variable is not present on the dashboard, navigate to a page where the booking calendar is rendered (e.g., a page with the [booking] or [bookingedit] shortcode) as these pages always load the booking JS.

5. Exploitation Strategy

Step 1: Authentication

Log in to the WordPress instance with a Subscriber account using the browser_navigate and http_request tools to maintain a session.

Step 2: Nonce Extraction

Navigate to the dashboard and extract the wpbc_ajax_nonce.

Step 3: Data Theft Request

Send a POST request to admin-ajax.php to fetch all bookings.

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=WPBC_AJAX_GET_BOOKINGS_DATA&nonce=[NONCE_HERE]&search_params[limit]=100&search_params[sort]=booking_id&search_params[sort_type]=DESC
    

Note: If WPBC_AJAX_GET_BOOKINGS_DATA does not work, try wpbc_get_bookings as the action.

Step 4: Parsing Response

The response should be a JSON object containing an array of bookings. Each booking object will contain keys like:

  • form_data_hashed (Unserialized PII)
  • email
  • name
  • second_name
  • phone
  • address
  • cost

6. Test Data Setup

  1. Create Target Data: As an Admin, create a booking.
    • Go to "Booking" -> "Add Booking".
    • Enter PII: Name: Victim User, Email: victim@example.com, Phone: 555-1234.
  2. Create Attacker Account:
    • Use WP-CLI: wp user create attacker attacker@example.com --role=subscriber --user_pass=password123.
  3. Ensure Plugin is Active: wp plugin activate booking.

7. Expected Results

  • Success: The HTTP response status is 200 OK.
  • Content: The JSON body contains a list of bookings, including the booking made by the Admin/Victim, revealing victim@example.com and Victim User.
  • Response Structure (Example):
    {
      "success": true,
      "data": [
        {
          "booking_id": "1",
          "email": "victim@example.com",
          "form_data": "...",
          "name": "Victim",
          "second_name": "User"
        }
      ]
    }
    

8. Verification Steps

  1. Check Output: Inspect the response body of the http_request for the string victim@example.com.
  2. WP-CLI Comparison: Run wp db query "SELECT email FROM wp_booking" and verify the emails match those leaked in the AJAX response.

9. Alternative Approaches

If the WPBC_AJAX_GET_BOOKINGS_DATA action is restricted or different in the specific minor version:

  • Search for other actions: Use grep -r "wp_ajax_" in the plugin directory to find any actions related to "listing", "export", or "table".
  • Shortcode Check: Check if the [booking_history] or [booking_listing] shortcodes are available. If they are, create a page with wp post create --post_content='[booking_listing]' and view it as the Subscriber. If the vulnerability is in the shortcode rendering logic (which often calls the same internal data functions), the PII will be displayed directly on the page.
  • Nonce Bypass: Check if the handler uses check_ajax_referer( 'wpbc_ajax_nonce', 'nonce', false ) (with the die parameter set to false). If so, try sending the request without a nonce or with an invalid one.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Booking Calendar plugin for WordPress is vulnerable to sensitive information exposure due to a missing authorization check in its AJAX handling logic. This allows authenticated users with Subscriber-level access to retrieve all booking records, including PII like names, email addresses, and phone numbers.

Vulnerable Code

// booking/core/admin/wpbc-admin-ajax.php

add_action( 'wp_ajax_WPBC_AJAX_GET_BOOKINGS_DATA', 'wpbc_ajax_get_bookings_data_handler' );

function wpbc_ajax_get_bookings_data_handler() {
    check_ajax_referer( 'wpbc_ajax_nonce', 'nonce' );

    // Missing current_user_can check

    $search_params = $_POST['search_params'];
    $bookings = wpbc_get_bookings_objects( $search_params );

    wp_send_json_success( $bookings );
}

Security Fix

--- a/booking/core/admin/wpbc-admin-ajax.php
+++ b/booking/core/admin/wpbc-admin-ajax.php
@@ -10,6 +10,10 @@
 function wpbc_ajax_get_bookings_data_handler() {
     check_ajax_referer( 'wpbc_ajax_nonce', 'nonce' );
 
+    if ( ! current_user_can( 'manage_bookings' ) ) {
+        wp_die( -1 );
+    }
+
     $search_params = $_POST['search_params'];
     $bookings = wpbc_get_bookings_objects( $search_params );

Exploit Outline

An authenticated Subscriber user first retrieves the 'wpbc_ajax_nonce' from the WordPress dashboard. The attacker then sends a POST request to /wp-admin/admin-ajax.php with the action 'WPBC_AJAX_GET_BOOKINGS_DATA' and the extracted nonce. The server, failing to verify the user's capability to manage bookings, returns a JSON response containing detailed booking data including names, email addresses, and phone numbers for all users.

Check if your site is affected.

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