CVE-2025-67574

Booking calendar, Appointment Booking System <= 3.2.30 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
3.2.31
Patched in
6d
Time to patch

Description

The Booking calendar, Appointment Booking System plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 3.2.30. 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<=3.2.30
PublishedDecember 15, 2025
Last updatedDecember 20, 2025
Affected pluginbooking-calendar

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the steps to identify and exploit the Missing Authorization vulnerability in the **Booking calendar, Appointment Booking System** plugin (versions <= 3.2.30). ### 1. Vulnerability Summary The vulnerability (CVE-2025-67574) arises because specific AJAX actions in the plug…

Show full research plan

This research plan outlines the steps to identify and exploit the Missing Authorization vulnerability in the Booking calendar, Appointment Booking System plugin (versions <= 3.2.30).

1. Vulnerability Summary

The vulnerability (CVE-2025-67574) arises because specific AJAX actions in the plugin are registered using the wp_ajax_nopriv_ hook (making them accessible to unauthenticated users) but fail to implement a current_user_can() capability check within the callback function. This allows an attacker to perform administrative or restricted actions, such as deleting bookings or modifying settings, depending on the specific function exposed.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Authentication: Unauthenticated (No login required).
  • Action Type: AJAX POST request.
  • Vulnerable Parameters: The action parameter and specific IDs (e.g., booking_id) or settings keys.
  • Preconditions: The plugin must be active. Some actions might require a valid WordPress nonce, though unauthenticated actions often leak these nonces in the frontend source code.

3. Code Flow (Target Identification)

Since source files are not provided, the security agent must first identify the specific vulnerable function by scanning the plugin directory:

  1. Search for unauthenticated AJAX hooks:
    grep -rn "wp_ajax_nopriv_" /var/www/html/wp-content/plugins/booking-calendar/
    
  2. Analyze the callbacks: For each action found (e.g., booking_action_delete), check the corresponding function for:
    • Absence of current_user_can(...).
    • Logic that performs database deletions ($wpdb->delete) or updates (update_option).
  3. Check for Nonce Verification: Look for check_ajax_referer or wp_verify_nonce. If present, note the action string used (e.g., 'booking-nonce').

4. Nonce Acquisition Strategy

If the vulnerable action requires a nonce (verified via check_ajax_referer), it is likely localized for the frontend booking form.

  1. Identify Shortcode: Find the main booking form shortcode:
    grep -rn "add_shortcode" /var/www/html/wp-content/plugins/booking-calendar/
    
  2. Create Trigger Page: Create a page containing that shortcode (e.g., [booking_calendar]) to force the plugin to load its assets.
    wp post create --post_type=page --post_status=publish --post_title="Booking Page" --post_content='[booking_calendar]'
    
  3. Navigate and Extract: Use the browser_navigate tool to go to the new page.
  4. Extract Nonce: Search the page source or use browser_eval to find the localized data.
    • Search pattern (example): Look for wp_localize_script variables like booking_ajax_obj or wpbc_global.
    • JS Command: browser_eval("window.wpbc_global?.nonce") (Verify variable name in source).

5. Exploitation Strategy

Assuming the identified vulnerable action is booking_delete (a common "unauthorized action" in such plugins):

  1. Request Construction:
    • URL: http://localhost:8080/wp-admin/admin-ajax.php
    • Method: POST
    • Headers: Content-Type: application/x-www-form-urlencoded
    • Payload:
      action=booking_delete&booking_id=[TARGET_ID]&nonce=[EXTRACTED_NONCE]
      
  2. Execution: Use the http_request tool to send the payload.
  3. Target ID Discovery: If an ID is required, the agent can try low integers (1, 2, 3) or fetch existing booking IDs via WP-CLI if permissions allow for testing purposes.

6. Test Data Setup

To verify the exploit, the environment must contain data to be "unauthorizedly" manipulated:

  1. Create a Booking: Use the plugin's frontend or WP-CLI (if available) to insert a booking into the custom table (usually wp_booking_calendar or similar).
    # Example (Table name may vary, verify with wp db tables)
    wp db query "INSERT INTO wp_booking_calendar (name, email) VALUES ('Victim', 'victim@example.com');"
    
  2. Note the ID: Retrieve the ID of the created booking.
    wp db query "SELECT id FROM wp_booking_calendar WHERE email='victim@example.com';"
    

7. Expected Results

  • Response: The server should return a 200 OK response, often containing JSON like {"success":true} or a simple 1 (standard for successful WordPress AJAX).
  • State Change: The targeted booking record should be removed from the database or the targeted setting should be updated.

8. Verification Steps

After the http_request, verify the impact using WP-CLI:

  1. Check Database:
    wp db query "SELECT * FROM wp_booking_calendar WHERE id=[TARGET_ID];"
    
    Success Criteria: The query returns no results.
  2. Check Options (if settings-based):
    wp option get [modified_option_name]
    

9. Alternative Approaches

  • Settings Overwrite: If the vulnerable action is save_settings, attempt to change users_can_register to 1 or modify the admin email to an attacker-controlled one.
  • SQL Injection check: If the authorization is missing, the parameters might also be unescaped. Test booking_id=1 OR 1=1 if the first attempt succeeds to check for broader impact.
  • Nonce Bypass: If check_ajax_referer is called with die=false (e.g., check_ajax_referer('act', 'nonce', false)), the agent should try the request without a nonce or with an invalid one, as the code might continue execution regardless of the result.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Booking calendar, Appointment Booking System plugin for WordPress is vulnerable to unauthorized access in versions up to 3.2.30 because several AJAX actions registered via the wp_ajax_nopriv_ hook lack capability checks. This allows unauthenticated attackers to perform administrative or restricted actions, such as deleting booking records or modifying plugin settings.

Exploit Outline

To exploit this vulnerability, an attacker identifies AJAX actions registered via wp_ajax_nopriv_ that perform sensitive operations (e.g., record deletion). The attacker first navigates to the plugin's frontend booking form to extract a valid security nonce, typically found in localized JavaScript objects like 'wpbc_global'. A POST request is then sent to /wp-admin/admin-ajax.php with the 'action' parameter set to the vulnerable hook, the extracted nonce, and relevant identifiers (e.g., booking_id) to execute the unauthorized action without authentication.

Check if your site is affected.

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