[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fNdo9ppR1B5G_BnJTABUnAjrMZmy4sMruNTs9796ENHM":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-2025-68024","addonify-woocommerce-wishlist-missing-authorization-to-unauthenticated-settings-update","Addonify – WooCommerce Wishlist \u003C= 2.0.15 - Missing Authorization to Unauthenticated Settings Update","The Addonify – WooCommerce Wishlist plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 2.0.15. This makes it possible for unauthenticated attackers to perform an unauthorized action.","addonify-wishlist",null,"\u003C=2.0.15","2.0.16","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-04 00:00:00","2026-02-25 14:38:29",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fe43f61e5-4b74-47d7-ad54-a8df682d1f75?source=api-prod",22,[],"researched",false,3,"This research plan targets **CVE-2025-68024**, a missing authorization vulnerability in the **Addonify – WooCommerce Wishlist** plugin.\n\n### 1. Vulnerability Summary\nThe Addonify – WooCommerce Wishlist plugin for WordPress (up to version 2.0.15) registers an AJAX handler designed to save plugin settings but fails to implement a capability check (e.g., `current_user_can('manage_options')`). Crucially, this handler is registered with the `wp_ajax_nopriv_` hook, making it accessible to unauthenticated users. An attacker can overwrite arbitrary plugin settings, which could lead to site defacement (via custom CSS\u002FHTML settings) or functional disruption (changing wishlist page mappings).\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `http:\u002F\u002F\u003Ctarget>\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Method:** `POST`\n*   **Action:** `addonify_wishlist_save_settings` (inferred based on plugin architecture)\n*   **Payload Parameter:** `settings` (usually an array or JSON string) and `nonce`.\n*   **Authentication:** None required (unauthenticated).\n*   **Preconditions:** The plugin must be active. A valid AJAX nonce may be required if the function calls `check_ajax_referer`.\n\n### 3. Code Flow (Inferred)\n1.  **Entry Point:** The plugin registers AJAX hooks in a class (likely `includes\u002Fadmin\u002Fclass-settings.php` or `includes\u002Fclass-addonify-wishlist.php`).\n    ```php\n    add_action( 'wp_ajax_addonify_wishlist_save_settings', array( $this, 'save_settings' ) );\n    add_action( 'wp_ajax_nopriv_addonify_wishlist_save_settings', array( $this, 'save_settings' ) ); \u002F\u002F Vulnerable hook\n    ```\n2.  **Handler Function:** The `save_settings` function is invoked.\n3.  **Security Check (Missing):** The function may call `check_ajax_referer('addonify_wishlist_nonce_action', 'nonce')` but fails to call `current_user_can('manage_options')`.\n4.  **Data Processing:** The function iterates through `$_POST['settings']`.\n5.  **Sink:** The function calls `update_option( 'addonify_wishlist_settings', $settings )`.\n\n### 4. Nonce Acquisition Strategy\nThe plugin localizes scripts for the admin and potentially the frontend. If the `save_settings` action is reachable via the frontend or shared logic, the nonce will be available in the global JS scope.\n\n1.  **Identify the Script Handle:** The plugin likely uses `addonify-wishlist-settings` or `addonify-wishlist-common`.\n2.  **Identify the Localization Object:** Search for `wp_localize_script`. The object is likely `addonify_wishlist_params` or `addonify_wishlist_obj`.\n3.  **Discovery Steps:**\n    *   Create a page containing the wishlist shortcode: `[addonify_wishlist]`.\n    *   Navigate to that page using `browser_navigate`.\n    *   Execute `browser_eval(\"addonify_wishlist_obj.nonce\")` or `browser_eval(\"addonify_wishlist_params.nonce\")` to find the correct key.\n    *   Note: If the nonce action is specifically for admin settings, it may not be exposed on the frontend. However, `wp_ajax_nopriv_` suggests the developer intended or accidentally allowed frontend access to this function.\n\n### 5. Exploitation Strategy\nWe will attempt to update the \"Wishlist Page\" setting or a similar configuration value to point to an arbitrary post ID, or inject custom text into a settings field.\n\n**Request Details:**\n*   **URL:** `http:\u002F\u002F\u003Ctarget>\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Method:** `POST`\n*   **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n*   **Parameters:**\n    *   `action`: `addonify_wishlist_save_settings` (Verify via grep)\n    *   `nonce`: `[EXTRACTED_NONCE]`\n    *   `settings[wishlist_page_id]`: `1` (or any valid ID)\n    *   `settings[wishlist_button_text]`: `HACKED_BY_AGENT`\n\n**Step-by-Step Plan:**\n1.  **Grep for Action:** Run `grep -r \"wp_ajax_nopriv_addonify_wishlist_save_settings\" .` to confirm the exact action name.\n2.  **Verify Sink:** Run `grep -A 20 \"function save_settings\" .` to see which option name is being updated (e.g., `addonify_wishlist_options`).\n3.  **Obtain Nonce:** Use the `browser_eval` method described in Section 4.\n4.  **Send Exploit:** Use `http_request` to send the malicious `POST` payload.\n\n### 6. Test Data Setup\n1.  **Install Plugin:** Ensure `addonify-wishlist` version 2.0.15 is installed.\n2.  **Create Trigger Page:**\n    ```bash\n    wp post create --post_type=page --post_title=\"Wishlist Test\" --post_status=publish --post_content='[addonify_wishlist]'\n    ```\n3.  **Identify Baseline:**\n    ```bash\n    wp option get addonify_wishlist_settings\n    ```\n\n### 7. Expected Results\n*   **HTTP Response:** A successful response (e.g., `{\"success\":true}` or `1`).\n*   **Database Change:** The WordPress option `addonify_wishlist_settings` (or similar) will be updated with the attacker-supplied values.\n\n### 8. Verification Steps\n1.  **Check Options via CLI:**\n    ```bash\n    wp option get addonify_wishlist_settings\n    ```\n    Confirm that `wishlist_button_text` is now `HACKED_BY_AGENT`.\n2.  **Verify Frontend:**\n    Navigate to the shop page and check if the wishlist button text has changed.\n\n### 9. Alternative Approaches\n*   **If `settings` expects JSON:** Try sending `settings={\"wishlist_button_text\":\"HACKED\"}`.\n*   **Missing Nonce:** If `check_ajax_referer` is not called at all, omit the `nonce` parameter entirely.\n*   **Option Overwrite:** If the code uses `update_option( $_POST['option_name'], ... )` without strict validation, this could escalate to a full site takeover by overwriting `default_role` or `users_can_register`. (Check the code for `$wpdb` or `update_option` calls with dynamic keys).","The Addonify – WooCommerce Wishlist plugin registers an AJAX action for saving settings using both wp_ajax_ and wp_ajax_nopriv_ hooks. Because the handler function lacks a capability check like current_user_can('manage_options'), unauthenticated users can overwrite the plugin's configuration via the admin-ajax.php endpoint.","\u002F\u002F includes\u002Fadmin\u002Fclass-settings.php (inferred based on plugin structure)\nadd_action( 'wp_ajax_addonify_wishlist_save_settings', array( $this, 'save_settings' ) );\nadd_action( 'wp_ajax_nopriv_addonify_wishlist_save_settings', array( $this, 'save_settings' ) );\n\n---\n\n\u002F\u002F includes\u002Fadmin\u002Fclass-settings.php (inferred)\npublic function save_settings() {\n    if ( isset( $_POST['nonce'] ) && ! wp_verify_nonce( $_POST['nonce'], 'addonify_wishlist_nonce' ) ) {\n        wp_send_json_error();\n    }\n\n    \u002F\u002F Missing capability check here\n    $settings = $_POST['settings'];\n    update_option( 'addonify_wishlist_settings', $settings );\n    wp_send_json_success();\n}","--- a\u002Fincludes\u002Fadmin\u002Fclass-settings.php\n+++ b\u002Fincludes\u002Fadmin\u002Fclass-settings.php\n@@ -10,7 +10,6 @@\n class Addonify_Wishlist_Settings {\n     public function __construct() {\n         add_action( 'wp_ajax_addonify_wishlist_save_settings', array( $this, 'save_settings' ) );\n-        add_action( 'wp_ajax_nopriv_addonify_wishlist_save_settings', array( $this, 'save_settings' ) );\n     }\n \n     public function save_settings() {\n+        if ( ! current_user_can( 'manage_options' ) ) {\n+            wp_send_json_error( array( 'message' => __( 'Unauthorized access.', 'addonify-wishlist' ) ) );\n+        }\n         check_ajax_referer( 'addonify_wishlist_nonce', 'nonce' );\n         $settings = $_POST['settings'];\n         update_option( 'addonify_wishlist_settings', $settings );","1. Extract a valid AJAX nonce: Visit the site frontend where the plugin is active (e.g., a page with the [addonify_wishlist] shortcode) and extract the 'nonce' value from the localized JavaScript object (e.g., addonify_wishlist_params.nonce).\n2. Construct a malicious payload: Create a POST request to \u002Fwp-admin\u002Fadmin-ajax.php with the 'action' parameter set to 'addonify_wishlist_save_settings'.\n3. Overwrite settings: Include a 'settings' parameter containing an array of plugin configuration keys and desired values (e.g., 'settings[wishlist_button_text]=INJECTED_VALUE').\n4. Submit the request: Send the POST request without authentication. If successful, the site's 'addonify_wishlist_settings' option will be updated with the provided payload.","gemini-3-flash-preview","2026-04-27 15:56:32","2026-04-27 15:57:28",{"type":34,"vulnerable_version":35,"fixed_version":11,"vulnerable_browse":36,"vulnerable_zip":37,"fixed_browse":38,"fixed_zip":39,"all_tags":40},"plugin","2.0.15","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Faddonify-wishlist\u002Ftags\u002F2.0.15","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Faddonify-wishlist.2.0.15.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Faddonify-wishlist\u002Ftags\u002F2.0.16","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Faddonify-wishlist.2.0.16.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Faddonify-wishlist\u002Ftags"]