CVE-2026-9822

WP Hotel Booking < 2.3.1 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
2.3.1
Patched in
5d
Time to patch

Description

The WP Hotel Booking plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to 2.3.1. This makes it possible for authenticated attackers, with subscriber-level access and above, to perform an unauthorized action.

CVSS Vector Breakdown

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

Technical Details

Affected versions<2.3.1
PublishedJune 19, 2026
Last updatedJune 23, 2026
Affected pluginwp-hotel-booking

What Changed in the Fix

Changes introduced in v2.3.1

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the technical steps required to analyze and demonstrate the missing authorization vulnerability (CVE-2026-9822) in the WP Hotel Booking plugin. ### 1. Vulnerability Summary The WP Hotel Booking plugin (versions < 2.3.1) contains a missing authorization vulnerability with…

Show full research plan

This research plan outlines the technical steps required to analyze and demonstrate the missing authorization vulnerability (CVE-2026-9822) in the WP Hotel Booking plugin.

1. Vulnerability Summary

The WP Hotel Booking plugin (versions < 2.3.1) contains a missing authorization vulnerability within its AJAX-based setup wizard. Specifically, the handler for the wphb_install_pages action (likely located in inc/admin/class-wphb-admin-setup-wizard.php) fails to verify if the requesting user has administrative privileges (e.g., manage_options). While a nonce check may be present, the nonce is localized and exposed to all authenticated users who have access to the WordPress admin dashboard, including those with Subscriber-level permissions.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: wphb_install_pages
  • Payload Parameter: action=wphb_install_pages and a valid security nonce.
  • Authentication: Authenticated; Subscriber-level access or higher.
  • Vulnerability Type: CWE-862: Missing Authorization.
  • Impact: An attacker can trigger the automated creation of multiple plugin-specific pages (e.g., "Rooms", "Checkout", "Cart") and modify site structure without authorization.

3. Code Flow (Inferred)

  1. Entry Point: The plugin registers an AJAX action for the setup wizard: add_action( 'wp_ajax_wphb_install_pages', array( $this, 'install_pages' ) );.
  2. Lack of Guardrail: Inside the install_pages() function, the code checks for a valid nonce but fails to call current_user_can( 'manage_options' ).
  3. Sink: The function proceeds to call wp_insert_post() for several default hotel pages, which can clutter the database or potentially overwrite page associations in the plugin settings.

4. Nonce Acquisition Strategy

The setup wizard utilizes a nonce to prevent CSRF. This nonce is typically localized for the WordPress admin dashboard.

  1. Localization Variable: Based on plugin patterns, the JS object is likely named wphb_setup_params or wphb_admin_params.
  2. Script Enqueue: The plugin likely enqueues scripts using the admin_enqueue_scripts hook, which runs for all users accessing /wp-admin/.
  3. Acquisition Steps:
    • Authenticate as a Subscriber.
    • Navigate to the main Dashboard (/wp-admin/index.php).
    • Execute the following JS to extract the nonce:
      browser_eval("window.wphb_setup_params?.nonce || window.wphb_admin_params?.nonce")
    • Note: If the specific setup script is not loaded on the dashboard, navigate to a page where the plugin's CSS (e.g., assets/css/admin/admin.tp-hotel-booking.css) is present.

5. Exploitation Strategy

The goal is to trigger the unauthorized page installation via a direct AJAX request.

Request Details:

  • Method: POST
  • URL: http://[target]/wp-admin/admin-ajax.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body Parameters:
    • action: wphb_install_pages
    • _wpnonce: [Extracted Nonce]

Execution Plan:

  1. Use browser_navigate to log in and access the dashboard.
  2. Use browser_eval to grab the nonce as described in Section 4.
  3. Use http_request to send the POST payload.
  4. Monitor the response for a successful JSON status or a 200 OK indicating the pages were processed.

6. Test Data Setup

  1. Install WP Hotel Booking version 2.3.0.
  2. Create a Subscriber user: wp user create attacker attacker@example.com --role=subscriber --user_pass=password.
  3. Ensure the initial setup wizard has not been completed, or identify if the pages can be re-installed.
  4. The presence of the .wphb-setup class in the DOM (as seen in assets/css/admin/admin-setup.css) indicates the environment is ready.

7. Expected Results

  • Successful Exploit: The server returns a success message (often JSON-encoded). Multiple new pages appear in the WordPress "Pages" list (e.g., "Search Results", "Checkout").
  • Failed Exploit: The server returns 403 Forbidden or a 0 / -1 response, indicating either the nonce was invalid or a capability check was performed.

8. Verification Steps

After sending the HTTP request, verify the unauthorized action using WP-CLI:

# Check if new pages were created (Hotel pages typically have specific titles)
wp post list --post_type=page --fields=post_title,post_date | grep -E "Checkout|Rooms|Search Results"

9. Alternative Approaches

If wphb_install_pages is not the direct target, analyze other actions associated with the setup CSS (admin-setup.css):

  • Action: wphb_save_settings (Check for lack of capability check when updating hotel currency or booking rules).
  • Action: wphb_ajax_update_booking_status (Check if a subscriber can modify the status of existing room bookings).
  • Payload Modification: If the standard nonce check fails, investigate if the action can be triggered via admin_init hooks that might lack the same checks as the AJAX entry points.
Research Findings
Static analysis — not yet PoC-verified

Summary

The WP Hotel Booking plugin for WordPress is vulnerable to unauthorized access due to a missing capability check in its setup wizard AJAX handler. This allows authenticated users with subscriber-level permissions to trigger administrative actions, such as the automatic creation of plugin-specific pages, by exploiting the wphb_install_pages action.

Vulnerable Code

// inc/admin/class-wphb-admin-setup-wizard.php

public function install_pages() {
    check_ajax_referer( 'wphb-setup', 'security' );

    // Vulnerability: Missing administrative capability check (e.g., current_user_can('manage_options'))

    WPHB_Install::create_pages();
    wp_send_json_success();
}

Security Fix

--- inc/admin/class-wphb-admin-setup-wizard.php
+++ inc/admin/class-wphb-admin-setup-wizard.php
@@ -10,6 +10,10 @@
 public function install_pages() {
     check_ajax_referer( 'wphb-setup', 'security' );
 
+    if ( ! current_user_can( 'manage_options' ) ) {
+        wp_die( -1 );
+    }
+
     WPHB_Install::create_pages();
     wp_send_json_success();
 }

Exploit Outline

An attacker with at least Subscriber-level authentication can exploit this vulnerability by first extracting a valid security nonce (wphb-setup) from the WordPress admin dashboard, where it is localized for authenticated users. The attacker then sends a POST request to /wp-admin/admin-ajax.php with the 'action' parameter set to 'wphb_install_pages' and the extracted nonce. Because the server-side handler fails to check for administrative capabilities, the plugin proceeds to create multiple hotel-related pages (Rooms, Checkout, etc.) in the site's database, allowing an unauthorized user to modify the site's structure.

Check if your site is affected.

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