CVE-2026-6818

VikBooking Hotel Booking Engine & PMS <= 1.8.8 - Unauthenticated Stored Cross-Site Scripting via 'special_requests' Parameter

highImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
7.2
CVSS Score
7.2
CVSS Score
high
Severity
1.8.9
Patched in
1d
Time to patch

Description

The VikBooking Hotel Booking Engine & PMS plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'special_requests' parameter in all 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.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.8.8
PublishedJuly 7, 2026
Last updatedJuly 8, 2026
Affected pluginvikbooking

What Changed in the Fix

Changes introduced in v1.8.9

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This vulnerability is a **Stored Cross-Site Scripting (XSS)** vulnerability in the **VikBooking Hotel Booking Engine & PMS** plugin. It allows unauthenticated attackers to inject malicious scripts into the `special_requests` parameter during a room reservation. The payload is stored in the database …

Show full research plan

This vulnerability is a Stored Cross-Site Scripting (XSS) vulnerability in the VikBooking Hotel Booking Engine & PMS plugin. It allows unauthenticated attackers to inject malicious scripts into the special_requests parameter during a room reservation. The payload is stored in the database and executed when an administrator views the reservation details in the WordPress dashboard.

1. Vulnerability Summary

  • Vulnerability: Stored Cross-Site Scripting (XSS)
  • Vulnerable Parameter: special_requests
  • Sink: The reservation details view in the admin dashboard (e.g., admin/helpers/widgets/booking_details.php and reservation list views).
  • Root Cause: The plugin fails to sanitize the special_requests input during order creation and fails to escape the output when rendering the booking details for administrators.
  • Authentication: None (Unauthenticated).

2. Attack Vector Analysis

  • Endpoint: The front-end booking confirmation page (typically a page containing the [vikbooking_search] or [vikbooking_room_details] shortcode).
  • Action: The final step of the booking process where customer details are submitted.
  • Payload Location: The special_requests HTTP POST parameter.
  • Preconditions: At least one room must be published and available for booking to reach the checkout step.

3. Code Flow

The plugin follows a Joomla-inspired architecture adapted for WordPress.

  1. Entry Point (Front-end): A user initiates a booking. At the "Customer Details" or "Review" step, the special_requests field is filled.
  2. Processing: The request is typically handled by a front-end controller (e.g., VikBookingController task saveorder or confirm).
  3. Storage: The VBOModelReservation::save() (or similar method in the reservation model) receives the data. It uses $app->input->get() or $app->input->post->getString() with insufficient filtering. The raw or poorly sanitized string is inserted into the #__vikbooking_orders table in the special_requests column.
  4. Sink (Admin): An administrator logs in and navigates to VikBooking > Reservations. When viewing the specific booking, the widget VikBookingAdminWidgetBookingDetails (defined in admin/helpers/widgets/booking_details.php) fetches the record:
    $q = $dbo->getQuery(true)
        ->select($dbo->qn('o') . '.*')
        ->from($dbo->qn('#__vikbooking_orders', 'o'));
    // ... filters ...
    $details = $dbo->loadAssoc();
    
  5. Execution: The $details['special_requests'] value is then echoed in an admin template without using esc_html() or similar WordPress escaping functions, causing the script to execute in the administrator's browser.

4. Nonce Acquisition Strategy

VikBooking does not typically use standard WordPress nonces for the unauthenticated booking flow. Instead, it uses a session-based token (Joomla style).

  1. Identify Shortcode: Locate a page with the [vikbooking_search] shortcode.
  2. Navigate Flow: Use browser_navigate to go through the booking steps (Search -> Select Room -> Customer Details).
  3. Extract Token: On the "Customer Details" page, there is usually a hidden input field with a name that is a 32-character MD5 hash and a value of 1.
    • Example: <input type="hidden" name="59d...a92" value="1" />.
  4. JS Extraction: Use browser_eval to find this token:
    // Find the hidden input that has a 32-char hex name and value '1'
    Array.from(document.querySelectorAll('input[type="hidden"]'))
      .find(i => /^[a-f0-9]{32}$/.test(i.name) && i.value === '1')?.name;
    
  5. Bypass: If the plugin does not enforce JSession::checkToken() for unauthenticated order saves (which is common to prevent session expiration issues during long checkouts), the request may succeed without it.

5. Exploitation Strategy

Step 1: Setup

  • Ensure a room exists and is bookable.
  • Note the room ID and a valid rate plan ID.

Step 2: Submission
The exploit involves mimicking the final POST request of the booking flow.

  • URL: http://localhost:8080/index.php?option=com_vikbooking&task=saveorder (or the URL of the booking page).
  • Method: POST
  • Payload:
    POST /wp-admin/admin-ajax.php?action=vikbooking_save_order HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    
    idroom=1&idtar=1&checkin=2026-10-10&checkout=2026-10-12&first_name=Attacker&last_name=XSS&email=hacker@example.com&phone=123456&special_requests=<script>alert(document.domain)</script>&[TOKEN]=1
    
    (Note: Parameter names may vary slightly; use Playwright to inspect the actual form on the Customer Details page).

Step 3: Triggering

  • Log in as Administrator.
  • Navigate to /wp-admin/admin.php?page=vikbooking&view=reservations.
  • Click on the "Edit" or "Details" icon for the new reservation.

6. Test Data Setup

  1. Create Room: Use WP-CLI or manual entry to ensure a room is available.
    • wp vikbooking room create --name="Luxury Suite" --units=5 --price=100 (assuming CLI exists) or via DB.
  2. Publish Page: Create a page with the search shortcode.
    • wp post create --post_type=page --post_title="Book Now" --post_status=publish --post_content='[vikbooking_search]'

7. Expected Results

  • The booking is successfully created.
  • When the admin views the reservation in the dashboard, an alert box appearing with the domain name (or a fetch to a collaborator) confirms the XSS execution in the admin's session.

8. Verification Steps

After the HTTP request:

  1. Check DB: Verify the payload is stored exactly as sent.
    wp db query "SELECT special_requests FROM wp_vikbooking_orders ORDER BY id DESC LIMIT 1"
    
  2. Check Admin Page Render: Use browser_navigate to the reservation details and check for the injected tag.

9. Alternative Approaches

  • Quote Request: If the booking flow is complex, the quote controller (admin/controllers/quote.php) might also be vulnerable if exposed to front-end users, using similar parameters.
  • Other Parameters: If special_requests is escaped, test first_name or last_name, as these are often stored in the same orders table and reflected in the same views.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.