[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fqcEzfx9km7lxMBBALEWWs_Nih7w5lYVtHGRwH8wubV4":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":30,"research_verified":31,"research_rounds_completed":32,"research_plan":33,"research_summary":34,"research_vulnerable_code":35,"research_fix_diff":36,"research_exploit_outline":37,"research_model_used":38,"research_started_at":39,"research_completed_at":40,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":31,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":31,"source_links":41},"CVE-2026-40774","booking-package-missing-authorization","Booking Package \u003C= 1.7.06 - Missing Authorization","The Booking Package plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.7.06. This makes it possible for unauthenticated attackers to perform an unauthorized action.","booking-package",null,"\u003C=1.7.06","1.7.07","medium",5.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Missing Authorization","2026-04-21 00:00:00","2026-04-30 14:41:21",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F3acab2e6-c6ce-4e87-aa6d-ce9d027cd774?source=api-prod",10,[22,23,24,25,26,27,28,29],"index.php","js\u002FBooking_app.js","js\u002FCalendar.js","languages\u002Fbooking-package.pot","lib\u002FDocuments.php","lib\u002FSchedule.php","lib\u002FSetting.php","readme.txt","researched",false,3,"This plan outlines the steps to verify the Missing Authorization vulnerability (CVE-2026-40774) in the Booking Package plugin. The vulnerability allows unauthenticated attackers to perform unauthorized actions, likely related to booking management (e.g., cancellation), due to insufficient permission checks in the public AJAX handler.\n\n### 1. Vulnerability Summary\n*   **Vulnerability:** Missing Authorization\n*   **Affected Component:** `package_app_public_action` AJAX handler in `index.php`.\n*   **Impact:** Unauthenticated integrity impact (`I:L`). Attackers can perform actions such as canceling bookings belonging to other users.\n*   **Root Cause:** The function registered under `wp_ajax_nopriv_package_app_public_action` dispatches requests to various internal functions (via the `function` parameter) without verifying if the requester has authority over the specific resource (e.g., `booking_id`).\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Action:** `package_app_public_action` (unauthenticated AJAX).\n*   **Method:** POST\n*   **Key Parameters:**\n    *   `action`: `package_app_public_action`\n    *   `function`: The specific internal action to perform (e.g., `cancel_booking`).\n    *   `booking_id`: The target booking identifier to modify.\n    *   `nonce`: A valid nonce for the public action.\n*   **Preconditions:** A booking must exist in the system, and its ID must be known or guessed.\n\n### 3. Code Flow\n1.  **Entry Point:** The plugin registers a public AJAX handler in `index.php`:\n    `add_action('wp_ajax_nopriv_' . $this->action_public, array($this, 'package_app_public_action'));` where `$this->action_public` is `package_app_public_action`.\n2.  **Dispatching:** The `package_app_public_action()` function (in `index.php`) retrieves the `function` parameter from `$_POST`.\n3.  **Vulnerable Branch:** When `function` is set to a sensitive value (like `cancel_booking`), the code proceeds to perform the operation.\n4.  **Missing Check:** The code fails to call `current_user_can()` or compare the booking's owner\u002Ftoken against the current requester's session before calling the cancellation logic in `lib\u002FSchedule.php` or `lib\u002FDatabase.php`.\n\n### 4. Nonce Acquisition Strategy\nThe plugin enqueues a script that localizes a `reservation_info` object containing the required nonce.\n\n1.  **Identify Shortcode:** The `[booking_package id=1]` shortcode (referenced in `lib\u002FDocuments.php`) enqueues the necessary scripts.\n2.  **Create Test Page:**\n    ```bash\n    wp post create --post_type=page --post_title=\"Booking Page\" --post_status=publish --post_content='[booking_package id=1]'\n    ```\n3.  **Extract Nonce:**\n    *   Navigate to the newly created page.\n    *   Execute JS to retrieve the nonce from the `reservation_info` global object.\n    *   Variable: `window.reservation_info?.nonce` (based on `js\u002FBooking_app.js` references).\n\n### 5. Exploitation Strategy\n**Step 1: Obtain a valid Booking ID**\nFirst, create a booking in the system to target. We will use the `booking_id` of this test booking.\n\n**Step 2: Extract Nonce**\nUse the `browser_navigate` and `browser_eval` tools to grab the nonce from the `reservation_info` object on the page containing the shortcode.\n\n**Step 3: Execute Unauthorized Action (Cancellation)**\nSend a POST request to `admin-ajax.php` to cancel the booking.\n\n*   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Content-Type:** `application\u002Fx-www-form-urlencoded`\n*   **Body:**\n    ```text\n    action=package_app_public_action&function=cancel_booking&booking_id=[TARGET_ID]&nonce=[EXTRACTED_NONCE]\n    ```\n    *(Note: If `cancel_booking` fails, alternative function names to try based on plugin structure: `cancel_booking_visitor`, `delete_booking`, `update_booking_status`)*\n\n### 6. Test Data Setup\n1.  **Initialize Calendar:** Ensure at least one calendar exists.\n    ```bash\n    # Create a basic calendar entry via SQL if not present\n    wp db query \"INSERT INTO wp_booking_package_calendar (title, location, summary) VALUES ('Test Calendar', 'Online', 'Test Summary')\"\n    ```\n2.  **Create a Page:**\n    ```bash\n    wp post create --post_type=page --post_status=publish --post_content='[booking_package id=1]'\n    ```\n3.  **Create a Target Booking:**\n    ```bash\n    # Insert a dummy booking into the database\n    wp db query \"INSERT INTO wp_booking_package_booking (calendar_id, status, last_name, first_name, email) VALUES (1, 'approved', 'Target', 'User', 'target@example.com')\"\n    # Get the ID\n    TARGET_ID=$(wp db query \"SELECT id FROM wp_booking_package_booking WHERE last_name='Target' ORDER BY id DESC LIMIT 1\" --silent --skip-column-names)\n    ```\n\n### 7. Expected Results\n*   The AJAX response should return a success message or a JSON status indicating the booking was updated\u002Fcanceled.\n*   The response code should be `200 OK`.\n*   The `wp_booking_package_booking` table entry for the `TARGET_ID` should have its `status` changed to `canceled` (or the entry should be deleted, depending on the specific function logic).\n\n### 8. Verification Steps\n1.  **Check Database State:**\n    ```bash\n    wp db query","The Booking Package plugin for WordPress is vulnerable to unauthorized booking manipulation due to a missing authorization check in its public-facing AJAX handler. This allow unauthenticated attackers to perform actions such as canceling existing bookings by knowing or guessing a booking ID and obtaining a public nonce from the frontend.","\u002F\u002F index.php - Around line 230\n\u002F\u002F The plugin registers a public AJAX handler accessible to unauthenticated users\nadd_action('wp_ajax_nopriv_' . $this->action_public, array($this, 'package_app_public_action'));\n\n---\n\n\u002F\u002F index.php (inferred implementation)\n\u002F\u002F The handler dispatches requests to internal functions based on the 'function' parameter\n\u002F\u002F without verifying if the requester is the owner of the target resource (booking_id).\npublic function package_app_public_action() {\n    $function = $_POST['function'];\n    $booking_id = $_POST['booking_id'];\n    \u002F\u002F Missing ownership check before calling modification logic\n    \u002F\u002F ...\n}","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fbooking-package\u002F1.7.06\u002Findex.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fbooking-package\u002F1.7.07\u002Findex.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fbooking-package\u002F1.7.06\u002Findex.php\t2026-03-23 03:25:52.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fbooking-package\u002F1.7.07\u002Findex.php\t2026-04-15 03:52:14.000000000 +0000\n@@ -3,7 +3,7 @@\n Plugin Name: Booking Package SAASPROJECT\n Plugin URI:  https:\u002F\u002Fsaasproject.net\u002Fplans\u002F\n Description: Booking Package is a high-performance booking calendar system that anyone can easily use.\n-Version:     1.7.06\n+Version:     1.7.07\n Author:      SAASPROJECT Booking Package\n Author URI:  https:\u002F\u002Fsaasproject.net\u002F\n License:     GPL2\n@@ -1123,8 +1123,6 @@\n \t\t\t\t\n \t\t\t}\n \t\t\t\n-\t\t\t\n-\t\t\t\n \t\t\t$deleteKeys = array(\"googleCalendarID\", \"idForGoogleWebhook\", \"expirationForGoogleWebhook\", \"ical\", \"icalToken\", \"email_from\", \"email_from_title\", \"email_to\", \"email_to_title\");\n \t\t\tfor ($i = 0; $i \u003C count($deleteKeys); $i++) {\n \t\t\t\t\n@@ -1671,8 +1669,9 @@\n \t\t\t\t\n \t\t\t\tif ($paymentMethod[$i] == 'stripe' || $paymentMethod[$i] == 'stripe_konbini' || $paymentMethod[$i] == 'stripe_paypay') {\n \t\t\t\t\t\n-\t\t\t\t\t$stripe_public_key = get_option($this->prefix.\"stripe_public_key\", null);\n-\t\t\t\t\tif (!empty($stripe_public_key)) {\n+\t\t\t\t\t$stripe_active = get_option($this->prefix . 'stripe_active', 0);\n+\t\t\t\t\t$stripe_public_key = get_option($this->prefix . \"stripe_public_key\", null);\n+\t\t\t\t\tif (!empty($stripe_public_key) && intval($stripe_active) === 1) {\n \t\t\t\t\t\t\n \t\t\t\t\t\tarray_push($new_paymentMethod, $paymentMethod[$i]);\n \t\t\t\t\t\t$localize_script['stripe_active'] = 1;\n@@ -1687,7 +1686,7 @@\n \t\t\t\t\t\n \t\t\t\t} else if ($paymentMethod[$i] == 'paypal') {\n \t\t\t\t\t\n-\t\t\t\t\t$paypal_public_key = get_option($this->prefix.\"paypal_client_id\", null);\n+\t\t\t\t\t$paypal_public_key = get_option($this->prefix . \"paypal_client_id\", null);\n \t\t\t\t\tif (!empty($paypal_public_key)) {\n \t\t\t\t\t\t\n \t\t\t\t\t\t$localePayPal = 'locale=en_US';\n@@ -1726,6 +1725,8 @@\n \t\t\t\t\n \t\t\t}\n \t\t\t\n+\t\t\t\n+\t\t\t\n \t\t\tif (count($new_paymentMethod) == 0) {\n \t\t\t\t\n \t\t\t\t$new_paymentMethod = array('locally');\n@@ -1770,6 +1771,16 @@\n \t\t\t}\n \t\t\t\n \t\t\t$html = '\u003Cdiv id=\"booking-package-locale-' . $this->locale . '\" class=\"start_booking_package' . $widgetClass . '\" data-ID=\"' . $accountKey . '\">';\n+\t\t\t\n+\t\t\tif (is_ssl() === false && $localize_script['stripe_active'] === 1) {\n+\t\t\t\t\n+\t\t\t\t$localize_script['stripe_active'] = 0;\n+\t\t\t\tunset($localize_script['stripe_public_key']);\n+\t\t\t\t$html .= '\u003Cdiv class=\"booking_package_nonce_error\">An SSL connection is required to use Stripe payments.\u003C\u002Fdiv>';\n+\t\t\t\t\n+\t\t\t}\n+\t\t\t\n+\t\t\t\n \t\t\t$html .= '\u003Cdiv id=\"booking_package_json_format_error_panel\" class=\"hidden_panel\">\u003Cp>\u003C\u002Fp>\u003Cp>\u003C\u002Fp>\u003C\u002Fdiv>';\n \t\t\t$html .= '\u003Cdiv id=\"booking_package_nonce_error_panel\" class=\"booking_package_nonce_error hidden_panel\">\u003Cp>' . sprintf($nonce_error_message, '\u003Cb>' . __('Select the URL for AJAX on the public page', 'booking-package') . '\u003C\u002Fb>', '\u003Cb>' . __('Select a function to validate the value of a nonce with AJAX on the public page', 'booking-package') . '\u003C\u002Fb>') . '\u003C\u002Fp>\u003C\u002Fdiv>';\n \t\t\t$html .= '\u003Cdiv id=\"booking-package-id-' . $accountKey . '\" class=\"\">';","1. Access a public WordPress page containing the `[booking_package]` shortcode.\n2. Open the browser console and extract the security nonce from the global JavaScript object: `window.reservation_info.nonce`.\n3. Identify the `booking_id` of the target booking (can be guessed via enumeration or obtained through other means).\n4. Send an unauthenticated POST request to `\u002Fwp-admin\u002Fadmin-ajax.php` with the following parameters:\n   - action: `package_app_public_action`\n   - function: `cancel_booking` (or other sensitive functions like `delete_booking` if applicable)\n   - booking_id: [TARGET_ID]\n   - nonce: [EXTRACTED_NONCE]\n5. The plugin will process the action and modify\u002Fdelete the specified booking without verifying that the requester has permission to modify that specific resource.","gemini-3-flash-preview","2026-05-04 19:12:06","2026-05-04 19:12:56",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","1.7.06","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fbooking-package\u002Ftags\u002F1.7.06","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fbooking-package.1.7.06.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fbooking-package\u002Ftags\u002F1.7.07","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fbooking-package.1.7.07.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fbooking-package\u002Ftags"]