[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fZAHqSpqKWHT4obDaGSG_0HrBzw1P11vJ3jQitiTzCEM":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-1980","wpbookit-missing-authorization-to-unauthenticated-sensitive-customer-data-exposure","WPBookit \u003C= 1.0.8 - Missing Authorization to Unauthenticated Sensitive Customer Data Exposure","The WPBookit plugin for WordPress is vulnerable to unauthorized data disclosure due to a missing authorization check on the 'get_customer_list' route in all versions up to, and including, 1.0.8. This makes it possible for unauthenticated attackers to retrieve sensitive customer information including names, emails, phone numbers, dates of birth, and gender.","wpbookit",null,"\u003C=1.0.8","1.0.9","medium",5.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:L\u002FI:N\u002FA:N","Exposure of Sensitive Information to an Unauthorized Actor","2026-03-03 12:28:50","2026-03-04 01:21:58",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fa1867c79-29d7-46a4-bfaf-c65e8a44c2ed?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,"# Exploitation Research Plan: CVE-2026-1980 (WPBookit \u003C= 1.0.8)\n\n## 1. Vulnerability Summary\nThe **WPBookit** plugin for WordPress is vulnerable to **Missing Authorization** in its internal AJAX routing system. Specifically, the route `get_customer_list` lacks any permission or nonce checks. Because the plugin registers both authenticated (`wp_ajax_`) and unauthenticated (`wp_ajax_nopriv_`) hooks for its central routing handler, any user (including unauthenticated visitors) can invoke the `get_customer_list` action. This results in the exposure of sensitive customer data, including full names, email addresses, phone numbers, dates of birth, and gender.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Action:** `wpb_ajax_get` (registered via `wp_ajax_nopriv_wpb_ajax_get`)\n- **Route Name:** `get_customer_list`\n- **Method:** `GET` (or `POST` since `$_REQUEST` is used in the handler)\n- **Authentication:** Unauthenticated (No login required)\n- **Preconditions:** At least one customer or guest must be registered in the system for the data to be returned.\n\n## 3. Code Flow\n1.  **Entry Point:** In `core\u002Fadmin\u002Fclasses\u002Fclass.wpb-admin-routes-handler.php`, the `event_Handler()` function registers:\n    ```php\n    add_action( \"wp_ajax_wpb_ajax_get\", [ $this, 'wpb_ajax_get' ] );\n    add_action( \"wp_ajax_nopriv_wpb_ajax_get\", [ $this, 'wpb_ajax_get' ] );\n    ```\n2.  **Routing Logic:** When `wpb_ajax_get` is called, it identifies the route from the `route_name` parameter:\n    ```php\n    $route_name = isset($_REQUEST['route_name']) ? sanitize_text_field(wp_unslash($_REQUEST['route_name'])) : '';\n    ```\n3.  **Permission Check Failure:** The handler only enforces permissions if a `permission` key is defined for the route in the route configuration:\n    ```php\n    if (isset($route['permission']) && !empty($route['permission'])) {\n        if (!is_user_logged_in() || !current_user_can($route['permission'])) {\n            \u002F\u002F Error thrown\n        }\n    }\n    ```\n4.  **Target Route:** In `core\u002Fadmin\u002Fclasses\u002Fclass.wpb-admin-routes.php`, the `get_customer_list` route is defined **without** a `permission` or `nonce` key:\n    ```php\n    'get_customer_list'    => [\n        'method' => 'get',\n        'action' => 'WPBOOKIT_Customer_Controller@get_customer_list',\n        'module' => 'customer-controller',\n        'dependency' => array(...)\n    ],\n    ```\n5.  **Sink:** The `call($route)` method is invoked, which executes `WPBOOKIT_Customer_Controller::get_customer_list()`, returning the customer database to the requester.\n\n## 4. Nonce Acquisition Strategy\nAccording to the code in `core\u002Fadmin\u002Fclasses\u002Fclass.wpb-admin-routes-handler.php`, **no nonce is required** for GET requests handled by `wpb_ajax_get`.\n\n- The `wpb_ajax_post` method checks `if ($route['nonce'] === 1)`.\n- The `wpb_ajax_get` method **omits** this block entirely.\n- The `get_customer_list` route in `class.wpb-admin-routes.php` does not define a `nonce` key regardless.\n\n**Conclusion:** No nonce acquisition is necessary for this exploit.\n\n## 5. Exploitation Strategy\nThe exploit involves a single HTTP GET request to the AJAX endpoint.\n\n### Step 1: Request Sensitive Data\nSend a GET request to retrieve the customer list. We include DataTable parameters (`draw`, `start`, `length`) because the backend controller (implied by `Customer.js`) likely expects them for pagination.\n\n**Request:**\n- **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php?action=wpb_ajax_get&route_name=get_customer_list&draw=1&start=0&length=10`\n- **Method:** `GET`\n- **Headers:** None required.\n\n**Expected Payload (in response JSON):**\nThe response should be a JSON object containing a `data` array. Each object in `data` will contain fields such as:\n- `id`\n- `name`\n- `email`\n- `phone`\n- `dob` (Date of Birth)\n- `gender`\n- `profile_img`\n\n## 6. Test Data Setup\nTo ensure the exploit returns data, at least one customer must exist in the database. Since unauthenticated users cannot usually register customers, we must set them up as an administrator first.\n\n1.  **Login as Admin.**\n2.  **Navigate to WPBookit > Customers.**\n3.  **Create a test customer** with specific data:\n    - First Name: `John`\n    - Last Name: `Doe`\n    - Email: `johndoe@example.com`\n    - Phone: `1234567890`\n    - DOB: `1990-01-01`\n    - Gender: `Male`\n4.  Alternatively, use WP-CLI to insert a record into the likely customer table (usually `wp_wpb_customers` or similar, check `wp db tables`).\n\n## 7. Expected Results\n- **Success:** The HTTP response status is `200 OK`. The body is a JSON object with `data` containing the customer `johndoe@example.com` and his PII.\n- **Failure:** The HTTP response status is `403 Forbidden` or `401 Unauthorized`, or the `data` array is empty (if no customers were created).\n\n## 8. Verification Steps\nAfter performing the HTTP request:\n1.  Verify the JSON structure matches the columns expected in `core\u002Fadmin\u002Fassets\u002Fsrc\u002Fmodule\u002FCustomer.js`.\n2.  Use WP-CLI to confirm the data retrieved matches the database:\n    ```bash\n    wp db query \"SELECT * FROM wp_wpb_customers;\"\n    ```\n    (Note: verify exact table name using `wp db tables | grep wpb`)\n\n## 9. Alternative Approaches\nIf `get_customer_list` is restricted for some reason (e.g., a silent patch), try other routes defined in `class.wpb-admin-routes.php` that also lack permission checks:\n- **Guest List:** `route_name=get_guest_list`\n- **Booking List:** `route_name=booking_list` (Note: this route has `nonce => 1` in config, but `wpb_ajax_get` might still ignore it due to the missing check in the handler).\n- **Booking Types:** `route_name=get_booking_type` (May reveal business-internal service details).","The WPBookit plugin for WordPress (versions 1.0.8 and earlier) exposes sensitive customer data because its central AJAX routing system lacks authorization and nonce checks for the 'get_customer_list' route. This allows unauthenticated attackers to retrieve a database of customer information, including full names, email addresses, phone numbers, dates of birth, and gender.","\u002F\u002F core\u002Fadmin\u002Fclasses\u002Fclass.wpb-admin-routes-handler.php:21\npublic function event_Handler() {\n    add_action( \"wp_ajax_wpb_ajax_post\", [ $this, 'wpb_ajax_post' ] );\n    add_action( \"wp_ajax_nopriv_wpb_ajax_post\", [ $this, 'wpb_ajax_post' ] );\n\n    add_action( \"wp_ajax_wpb_ajax_get\", [ $this, 'wpb_ajax_get' ] );\n    add_action( \"wp_ajax_nopriv_wpb_ajax_get\", [ $this, 'wpb_ajax_get' ] );\n}\n\n---\n\n\u002F\u002F core\u002Fadmin\u002Fclasses\u002Fclass.wpb-admin-routes-handler.php:151\n\u002F\u002F Handler only enforces permissions if a 'permission' key is defined for the route\nif (isset($route['permission']) && !empty($route['permission'])) {\n    if (!is_user_logged_in() || !current_user_can($route['permission'])) {\n        $error = __('You do not have permission to perform this action.', 'wpbookit');\n        throw new Exception($error, 403);\n    }\n}\n\n---\n\n\u002F\u002F core\u002Fadmin\u002Fclasses\u002Fclass.wpb-admin-routes.php:143\n'get_customer_list'    => [\n    'method' => 'get',\n    'action' => 'WPBOOKIT_Customer_Controller@get_customer_list',\n    'module' => 'customer-controller',\n    'dependency' => array(\n        IQWPB_PLUGIN_PATH . \"core\u002Fincludes\u002Fwpb-core-functions.php\",\n        IQWPB_PLUGIN_PATH . \"core\u002Fadmin\u002Fclasses\u002Fsettings\u002Fclass.wpb-settings-page.php\",\n        IQWPB_PLUGIN_PATH . \"core\u002Fadmin\u002Fclasses\u002Fsettings\u002Fclass.wpb-settings-customer.php\",\n    )\n],","--- \u002Fcore\u002Fadmin\u002Fclasses\u002Fclass.wpb-admin-routes.php\n+++ \u002Fcore\u002Fadmin\u002Fclasses\u002Fclass.wpb-admin-routes.php\n@@ -147,6 +147,7 @@\n                 'get_customer_list'    => [\n                     'method' => 'get',\n                     'action' => 'WPBOOKIT_Customer_Controller@get_customer_list',\n+                    'permission' => 'manage_options',\n                     'module' => 'customer-controller',\n                     'dependency' => array(\n                         IQWPB_PLUGIN_PATH . \"core\u002Fincludes\u002Fwpb-core-functions.php\",","The exploit is achieved by sending a single unauthenticated HTTP GET request to the WordPress AJAX endpoint. \n\n1. Target the endpoint: \u002Fwp-admin\u002Fadmin-ajax.php\n2. Set the 'action' parameter to 'wpb_ajax_get' (which triggers the vulnerable nopriv handler).\n3. Set the 'route_name' parameter to 'get_customer_list' (which lacks any 'permission' or 'nonce' definition in the plugin's route configuration).\n4. Include standard DataTable parameters (e.g., 'draw=1', 'start=0', 'length=10') to ensure the backend controller processes the request and returns the paginated data.\n5. The server will respond with a 200 OK and a JSON object containing a 'data' array populated with customer PII (names, emails, phones, DOBs).","gemini-3-flash-preview","2026-04-18 06:44:07","2026-04-18 06:44:34",{"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"]