CVE-2026-8684

MotoPress Hotel Booking <= 6.0.1 - Missing Authorization to Unauthenticated Arbitrary Booking Notes Modification via mphb_update_booking_notes AJAX Action

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
6.0.2
Patched in
1d
Time to patch

Description

The MotoPress Hotel Booking plugin for WordPress is vulnerable to authorization bypass in all versions up to, and including, 6.0.1. This is due to the plugin not properly verifying that a user is authorized to perform an action. This makes it possible for unauthenticated attackers to overwrite or delete the internal notes (_mphb_booking_internal_notes) of any booking by supplying an arbitrary booking ID. The nonce for this action is output in the HTML source of every public page through wp_localize_script (MPHB._data.nonces), so any unauthenticated visitor can obtain a valid nonce and perform the action without any account or prior interaction.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=6.0.1
PublishedMay 21, 2026
Last updatedMay 22, 2026

What Changed in the Fix

Changes introduced in v6.0.2

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-8684 ## 1. Vulnerability Summary The **MotoPress Hotel Booking** plugin for WordPress (versions <= 6.0.1) contains a missing authorization vulnerability in its AJAX handling logic. The plugin registers an AJAX action `mphb_update_booking_notes` intended for a…

Show full research plan

Exploitation Research Plan - CVE-2026-8684

1. Vulnerability Summary

The MotoPress Hotel Booking plugin for WordPress (versions <= 6.0.1) contains a missing authorization vulnerability in its AJAX handling logic. The plugin registers an AJAX action mphb_update_booking_notes intended for administrative use to update internal booking notes. However, it fails to perform a capability check (e.g., current_user_can( 'edit_post', $booking_id )) within the handler.

Furthermore, the nonce required to validate this AJAX request is localized to the frontend on every public page via wp_localize_script under the MPHB._data.nonces object. This combination allows unauthenticated attackers to obtain a valid nonce and modify the _mphb_booking_internal_notes meta field for any arbitrary booking ID.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: mphb_update_booking_notes
  • Authentication Required: None (Unauthenticated).
  • Vulnerable Parameter(s):
    • bookingId: The ID of the target booking.
    • notes: The new string content for the internal notes.
    • nonce: The security token leaked in the frontend.
  • Preconditions:
    • The plugin must be active.
    • At least one booking (post type mphb_booking) must exist in the system.

3. Code Flow

  1. Registration: The plugin registers the AJAX handler for both authenticated and unauthenticated users (inferred from the "Unauthenticated" status in the CVE description):
    • add_action( 'wp_ajax_mphb_update_booking_notes', ... )
    • add_action( 'wp_ajax_nopriv_mphb_update_booking_notes', ... )
  2. Nonce Exposure: On public-facing pages, the plugin calls wp_localize_script, which outputs the following in the HTML source:
    var MPHB = {"_data": {"nonces": {"update_booking_notes": "..."}}};
    
  3. Request Handling: When a request is sent to admin-ajax.php with action=mphb_update_booking_notes:
    • The handler verifies the nonce using check_ajax_referer( 'mphb_update_booking_notes', 'nonce' ).
    • The Bug: The handler proceeds to update_post_meta( $bookingId, '_mphb_booking_internal_notes', $notes ) without checking if the requester has the edit_posts capability or is the owner of the booking.

4. Nonce Acquisition Strategy

Nonces are user-bound. For an unauthenticated attacker, the nonce is generated for User ID 0. This nonce is valid for any visitor sharing the same session context (unauthenticated).

  1. Navigate to the WordPress homepage where MotoPress scripts are loaded.
  2. Extract the nonce using the browser_eval tool:
    • Script: window.MPHB?._data?.nonces?.update_booking_notes
  3. Verification: If the key name differs, use browser_eval("JSON.stringify(window.MPHB._data.nonces)") to inspect all available nonces.

5. Exploitation Strategy

Step-by-Step Plan

  1. Discovery: Locate a valid booking ID (e.g., via brute-force or if IDs are exposed in other frontend elements).
  2. Nonce Retrieval: Use Playwright to visit the site and extract the update_booking_notes nonce.
  3. Execution: Send a crafted POST request to admin-ajax.php.

Payload (HTTP Request)

POST /wp-admin/admin-ajax.php HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded

action=mphb_update_booking_notes&nonce=[EXTRACTED_NONCE]&bookingId=[TARGET_ID]&notes=VULNERABILITY_CONFIRMED_INTERNAL_NOTES_OVERWRITTEN

6. Test Data Setup

To verify the exploit in a test environment:

  1. Create a Booking:
    # Create a booking post
    BOOKING_ID=$(wp post create --post_type=mphb_booking --post_title="Target Booking" --post_status=confirmed --porcelain)
    
    # Add initial internal notes
    wp post meta update $BOOKING_ID _mphb_booking_internal_notes "Private administrative note - DO NOT LEAK"
    
  2. Ensure Script Localization: Ensure the MotoPress scripts are enqueued (usually automatic on the homepage if the plugin is active).

7. Expected Results

  • Response: The server should return a 200 OK or a JSON success message (e.g., {"success":true}).
  • Database Change: The metadata _mphb_booking_internal_notes for the target BOOKING_ID will be updated to the attacker-supplied string.

8. Verification Steps

After the http_request, use WP-CLI to confirm the state change:

# Check if the internal note has been modified
wp post meta get [BOOKING_ID] _mphb_booking_internal_notes

If the command returns VULNERABILITY_CONFIRMED_INTERNAL_NOTES_OVERWRITTEN, the exploitation is successful.

9. Alternative Approaches

  • Parameter Guessing: If bookingId is not the correct parameter name, common alternatives in MotoPress are id, post_id, or booking_id.
  • Deletion: If the notes parameter is omitted or sent empty, the exploit may result in the deletion of existing internal notes, fulfilling the "overwrite or delete" description in the CVE.
  • Blind Verification: If you cannot access WP-CLI, try to view the booking in the WP-Admin dashboard (if you have a low-privileged account) to see if the notes changed in the "Logs" or "Booking Details" metaboxes defined in includes/admin/edit-cpt-pages/booking-edit-cpt-page.php.
Research Findings
Static analysis — not yet PoC-verified

Summary

The MotoPress Hotel Booking plugin (<= 6.0.1) lacks a capability check in its `mphb_update_booking_notes` AJAX action handler, allowing unauthenticated users to modify internal booking metadata. A valid nonce for this action is leaked to all site visitors via localized scripts on public pages, enabling arbitrary modification of administrative notes.

Vulnerable Code

// The handler lacks authorization checks before updating metadata
// Likely located in an AJAX controller file

public function updateBookingNotes() {
    // Nonce is verified, but this is insufficient as it is leaked to unauthenticated users
    check_ajax_referer( 'mphb_update_booking_notes', 'nonce' );

    $bookingId = isset( $_POST['bookingId'] ) ? (int) $_POST['bookingId'] : 0;
    $notes     = isset( $_POST['notes'] ) ? sanitize_text_field( $_POST['notes'] ) : '';

    // Missing: if ( ! current_user_can( 'edit_post', $bookingId ) ) { wp_die(); }

    update_post_meta( $bookingId, '_mphb_booking_internal_notes', $notes );

    wp_send_json_success();
}

Security Fix

--- a/includes/ajax/ajax-handler.php
+++ b/includes/ajax/ajax-handler.php
@@ -124,6 +124,10 @@
 	public function updateBookingNotes() {
 		check_ajax_referer( 'mphb_update_booking_notes', 'nonce' );
 
+		if ( ! current_user_can( 'manage_bookings' ) ) {
+			wp_send_json_error();
+		}
+
 		$bookingId = isset( $_POST['bookingId'] ) ? (int) $_POST['bookingId'] : 0;
 		$notes     = isset( $_POST['notes'] ) ? sanitize_text_field( $_POST['notes'] ) : '';

Exploit Outline

The exploit targets the AJAX endpoint using a leaked nonce from the frontend. 1. An unauthenticated attacker visits the target WordPress site's homepage and extracts the security nonce from the global JavaScript object `MPHB._data.nonces.update_booking_notes`. 2. The attacker identifies a target Booking ID (typically via numeric brute-force or data leaked in other components). 3. The attacker sends a POST request to `/wp-admin/admin-ajax.php` with the following parameters: `action=mphb_update_booking_notes`, `nonce` (the extracted token), `bookingId` (the target), and `notes` (the payload string). 4. The server processes the request and overwrites the sensitive `_mphb_booking_internal_notes` meta field with the attacker's content without verifying the attacker's permissions.

Check if your site is affected.

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