MotoPress Hotel Booking <= 6.0.1 - Missing Authorization to Unauthenticated Arbitrary Booking Notes Modification via mphb_update_booking_notes AJAX Action
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:NTechnical Details
<=6.0.1What Changed in the Fix
Changes introduced in v6.0.2
Source Code
WordPress.org SVN# 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
- 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', ... )
- 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": "..."}}}; - Request Handling: When a request is sent to
admin-ajax.phpwithaction=mphb_update_booking_notes:- The handler verifies the
nonceusingcheck_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 theedit_postscapability or is the owner of the booking.
- The handler verifies the
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).
- Navigate to the WordPress homepage where MotoPress scripts are loaded.
- Extract the nonce using the
browser_evaltool:- Script:
window.MPHB?._data?.nonces?.update_booking_notes
- Script:
- 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
- Discovery: Locate a valid booking ID (e.g., via brute-force or if IDs are exposed in other frontend elements).
- Nonce Retrieval: Use Playwright to visit the site and extract the
update_booking_notesnonce. - Execution: Send a crafted
POSTrequest toadmin-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]¬es=VULNERABILITY_CONFIRMED_INTERNAL_NOTES_OVERWRITTEN
6. Test Data Setup
To verify the exploit in a test environment:
- 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" - 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 OKor a JSON success message (e.g.,{"success":true}). - Database Change: The metadata
_mphb_booking_internal_notesfor the targetBOOKING_IDwill 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
bookingIdis not the correct parameter name, common alternatives in MotoPress areid,post_id, orbooking_id. - Deletion: If the
notesparameter 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.
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
@@ -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.