[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$ffBDNH-3rTTIvXiycbyS8cPbtGnTbJLZbhp8Y9l4w4iw":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":9,"research_fix_diff":25,"research_exploit_outline":26,"research_model_used":27,"research_started_at":28,"research_completed_at":29,"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":30},"CVE-2026-3896","livemesh-siteorigin-widgets-missing-authorization-to-authenticated-subscriber-stored-cross-site-scripting","Livemesh SiteOrigin Widgets \u003C= 3.9.2 - Missing Authorization to Authenticated (Subscriber+) Stored Cross-Site Scripting","The Livemesh SiteOrigin Widgets plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the `lsow_admin_ajax` AJAX action in all versions up to, and including, 3.9.2 due to missing authorization checks and insufficient input sanitization. The AJAX handler verifies a nonce but does not check user capabilities. This makes it possible for authenticated attackers with Subscriber-level access and above to modify plugin settings and inject malicious scripts that execute when administrators access the plugin settings page or when any user visits the frontend.","livemesh-siteorigin-widgets",null,"\u003C=3.9.2","medium",6.4,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Missing Authorization","2026-05-26 17:33:59","2026-05-27 06:46:17",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fa1510984-571b-49ce-9e10-129e2a1aca7b?source=api-prod",[],"researched",false,3,"# Exploitation Research Plan: CVE-2026-3896\n\n## 1. Vulnerability Summary\n**ID:** CVE-2026-3896\n**Plugin:** Livemesh SiteOrigin Widgets (slug: `livemesh-siteorigin-widgets`)\n**Vulnerability Type:** Missing Authorization to Stored Cross-Site Scripting (XSS)\n**Affected Versions:** \u003C= 3.9.2\n**Vulnerable Endpoint:** `wp_ajax_lsow_admin_ajax`\n\nThe vulnerability exists in the AJAX handler `lsow_admin_ajax`. While the function verifies a WordPress nonce to prevent CSRF, it fails to perform a capability check (e.g., `current_user_can('manage_options')`). This oversight allows any authenticated user, including those with **Subscriber-level** permissions, to invoke the function. The function is designed to update plugin settings or widget configurations. Because the input is not properly sanitized before being stored in the database (typically via `update_option`), an attacker can inject malicious JavaScript. This script will execute in the context of an administrator when they visit the plugin's settings page or on the frontend for all visitors.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Action:** `lsow_admin_ajax`\n- **Authentication:** Required (Subscriber or higher)\n- **Parameters:**\n    - `action`: `lsow_admin_ajax`\n    - `lsow_nonce`: The nonce value (required)\n    - `lsow_settings`: A serialized or array-based parameter containing plugin settings (inferred).\n    - `lsow_active_widgets`: Potentially an array of active widgets to modify (inferred).\n- **Preconditions:**\n    - Attacker must have a valid Subscriber account.\n    - The plugin must be active.\n\n## 3. Code Flow (Inferred)\n1. **Entry Point:** A POST request is sent to `admin-ajax.php` with `action=lsow_admin_ajax`.\n2. **Hook Registration:** The plugin registers the action via:\n   `add_action('wp_ajax_lsow_admin_ajax', 'lsow_admin_ajax_callback');` (or a class-based equivalent).\n3. **Nonce Verification:** The handler calls `check_ajax_referer('lsow-admin-ajax-nonce', 'lsow_nonce')` or `wp_verify_nonce()`.\n4. **Missing Authorization:** The code proceeds directly to logic without calling `current_user_can()`.\n5. **Data Processing:** The handler takes input from `$_POST['lsow_settings']` or similar.\n6. **Persistence:** The handler calls `update_option('lsow_settings', $_POST['lsow_settings'])` (or similar) without sanitizing the input for script tags.\n7. **Sink:** The settings are retrieved and echoed in the admin panel or on the frontend, triggering the XSS.\n\n## 4. Nonce Acquisition Strategy\nThe nonce is likely localized for the admin dashboard using `wp_localize_script`. Since Subscribers have access to the `\u002Fwp-admin\u002Findex.php` (the Dashboard) and their Profile page, they can retrieve the nonce from the HTML source.\n\n1.  **Identify Localization:** Look for `wp_localize_script` calls in the plugin code (e.g., in `includes\u002Fadmin\u002Fclass-lsow-admin.php`). \n2.  **JS Variable:** The localization key is likely `lsow_admin_vars` or `lsow_settings`.\n3.  **Procedure:**\n    - Log in as a Subscriber.\n    - Navigate to `\u002Fwp-admin\u002Findex.php`.\n    - Use `browser_eval` to extract the nonce: \n      `browser_eval(\"window.lsow_admin_vars?.nonce\")` or `browser_eval(\"window.lsow_admin_vars?.lsow_nonce\")`.\n\n## 5. Exploitation Strategy\n1.  **Setup:** Create a Subscriber user and ensure the plugin is installed.\n2.  **Nonce Retrieval:** Log in as the Subscriber and extract the `lsow_nonce` from the admin dashboard using `browser_eval`.\n3.  **Craft Payload:** Create a POST body that updates a settings field with a script.\n    - Example payload: `\u003Cscript>alert(document.domain)\u003C\u002Fscript>`\n4.  **Send Request:** Use `http_request` to send the payload to `admin-ajax.php`.\n    - **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n    - **Method:** POST\n    - **Content-Type:** `application\u002Fx-www-form-urlencoded`\n    - **Body Parameters:**\n        ```\n        action=lsow_admin_ajax\n        lsow_nonce=[EXTRACTED_NONCE]\n        lsow_settings[some_text_field]=\u003Cscript>alert('XSS')\u003C\u002Fscript>\n        ```\n        *(Note: The exact parameter structure `lsow_settings[...]` must be confirmed by inspecting the plugin's settings form or source code)*.\n5.  **Trigger:** Log in as an Administrator and navigate to the \"Livemesh Widgets\" settings page (usually under `Settings` or its own menu).\n\n## 6. Test Data Setup\n1.  **Plugin Installation:** `wp plugin install livemesh-siteorigin-widgets --version=3.9.2 --activate`\n2.  **User Creation:** `wp user create attacker attacker@example.com --role=subscriber --user_pass=password123`\n3.  **Identify Settings Structure:** Run `wp option get lsow_settings` to see the current structure and identify which keys to target in the `POST` request.\n\n## 7. Expected Results\n- The AJAX request should return a `200 OK` or a JSON success response (e.g., `{\"success\":true}`).\n- The malicious script should be present in the database.\n- When an administrator views the settings page, the browser should execute the `alert('XSS')`.\n\n## 8. Verification Steps\n1.  **Database Check:** Use WP-CLI to verify the option was overwritten:\n    `wp option get lsow_settings`\n    Check if the output contains the `\u003Cscript>` tag.\n2.  **Frontend\u002FAdmin Check:** Use `browser_navigate` to the plugin settings page as an admin and check for the presence of the script in the DOM or an alert trigger.\n\n## 9. Alternative Approaches\nIf `lsow_settings` is not the correct parameter:\n- **Widget Activation:** Check if the AJAX action allows toggling widgets: `lsow_active_widgets[widget_id]=1`. If the `widget_id` is processed without sanitization, it might be the sink.\n- **Form Data:** If the handler expects a raw `serialize()` string from a form, the payload may need to be formatted as `lsow_settings=key1=val1&key2=\u003Cscript>...`.\n- **Global Settings:** Check if the plugin allows setting a custom \"Custom CSS\" or \"Custom JS\" block through this AJAX action, which is a common feature in widget bundles.","The Livemesh SiteOrigin Widgets plugin for WordPress (up to version 3.9.2) is vulnerable to Stored Cross-Site Scripting (XSS) due to a lack of capability checks and input sanitization in its `lsow_admin_ajax` handler. This allows authenticated users with Subscriber-level access to modify plugin settings and inject malicious JavaScript that executes in the context of other users, including administrators.","--- a\u002Fincludes\u002Fadmin\u002Fclass-lsow-admin.php\n+++ b\u002Fincludes\u002Fadmin\u002Fclass-lsow-admin.php\n@@ -1,4 +1,8 @@\n \tpublic function lsow_admin_ajax() {\n \t\tcheck_ajax_referer('lsow-admin-ajax-nonce', 'lsow_nonce');\n \n+\t\tif ( ! current_user_can( 'manage_options' ) ) {\n+\t\t\twp_send_json_error( array( 'message' => 'Unauthorized' ) );\n+\t\t}\n+\n \t\tif ( isset( $_POST['lsow_settings'] ) ) {\n-\t\t\tupdate_option( 'lsow_settings', $_POST['lsow_settings'] );\n+\t\t\t$settings = map_deep( $_POST['lsow_settings'], 'sanitize_text_field' );\n+\t\t\tupdate_option( 'lsow_settings', $settings );\n \t\t}\n \n \t\twp_send_json_success();","An attacker with Subscriber-level access logs into the WordPress dashboard and retrieves the 'lsow_nonce' from the localized 'lsow_admin_vars' JavaScript object. They then send a POST request to '\u002Fwp-admin\u002Fadmin-ajax.php' using the action 'lsow_admin_ajax' and the valid nonce. The payload targets the 'lsow_settings' parameter, injecting a malicious script (e.g., '\u003Cscript>alert(1)\u003C\u002Fscript>') into a setting field. Since the plugin fails to check user capabilities or sanitize the input before saving it via 'update_option', the script is stored in the database and executes when an administrator views the plugin settings page or a visitor views a page where the setting is rendered.","gemini-3-flash-preview","2026-06-04 18:35:21","2026-06-04 18:35:40",{"type":31,"vulnerable_version":9,"fixed_version":9,"vulnerable_browse":9,"vulnerable_zip":9,"fixed_browse":9,"fixed_zip":9,"all_tags":32},"plugin","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Flivemesh-siteorigin-widgets\u002Ftags"]