KIA Subtitle <= 4.0.1 - [Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')]
Description
The KIA Subtitle plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the plugin's `the-subtitle` shortcode `before` and `after` attributes in all versions up to, and including, 4.0.1. This is 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:NTechnical Details
What Changed in the Fix
Changes introduced in v4.0.2
Source Code
WordPress.org SVNThis research plan outlines the process for analyzing and demonstrating the Stored Cross-Site Scripting (XSS) vulnerability in the **KIA Subtitle** plugin (CVE-2026-7509). ### 1. Vulnerability Summary The KIA Subtitle plugin is vulnerable to **Stored Cross-Site Scripting** via the `[the-subtitle]` …
Show full research plan
This research plan outlines the process for analyzing and demonstrating the Stored Cross-Site Scripting (XSS) vulnerability in the KIA Subtitle plugin (CVE-2026-7509).
1. Vulnerability Summary
The KIA Subtitle plugin is vulnerable to Stored Cross-Site Scripting via the [the-subtitle] shortcode. The vulnerability exists because the plugin's shortcode handler accepts before and after attributes from the user and outputs them to the page without proper sanitization or escaping (e.g., using esc_html() or wp_kses()). An authenticated attacker with Contributor permissions can create a post containing this shortcode with malicious JavaScript in the attributes, which will execute in the context of any user viewing the post.
2. Attack Vector Analysis
- Endpoint: WordPress Post Editor (via
post.phpor REST API) - Vulnerable Component: Shortcode callback function for
[the-subtitle] - Payload Location: Shortcode attributes
beforeand/orafter - Authentication Level: Contributor or higher (any role capable of using shortcodes in post content)
- Precondition: The post must have a subtitle value set (via the
kia_subtitlemeta field) for the shortcode to generate output.
3. Code Flow
- Registration: In
kia-subtitle.php, the shortcode is registered in the constructor:add_shortcode( 'the-subtitle', array( $this, 'shortcode' ) );(Line 126). - Attribute Handling: The
shortcode()method (inferred) likely usesshortcode_atts()to extractbeforeandafter. - Core Function Call: The shortcode method likely calls the helper function
the_subtitle()(documented inreadme.txt) orget_the_subtitle(). - The Sink: The
the_subtitle()function (or the shortcode handler itself) concatenates the$beforeand$afterstrings with the subtitle content and returns/echoes the result. Because these strings are not passed through escaping functions before being returned to the WordPress content filter, the injected HTML/JavaScript is rendered by the browser.
4. Nonce Acquisition Strategy
Since the vulnerability is a Stored XSS triggered by a Contributor-level user saving a post, we need to acquire the standard WordPress nonces required for post creation.
- Authentication: Authenticate as a Contributor user using
wp-login.php. - Access Editor: Navigate to
wp-admin/post-new.php. - Extract Nonce: Use
browser_evalto extract the_wpnoncefrom the page source or thewp-noncerequired for the REST API if using the Block Editor.- For the Classic Editor (used by default if Gutenberg is disabled):
document.querySelector('#_wpnonce').value. - For the REST API (Gutenberg): The nonce is typically found in
wpApiSettings.nonce.
- For the Classic Editor (used by default if Gutenberg is disabled):
5. Exploitation Strategy
The goal is to create a post as a Contributor that executes an alert when viewed by an Admin.
- Setup Phase:
- Use
wp-clito create a Contributor user and a post. - Crucially, set a value for the
kia_subtitlemeta key so the shortcode produces output.
- Use
- Execution Phase (HTTP):
- Step 1: Log in as the Contributor.
- Step 2: Update a post's content to include the malicious shortcode.
- Payload:
[the-subtitle before='<script>alert("XSS_BEFORE")</script>' after='<script>alert("XSS_AFTER")</script>']
- HTTP Request Details:
- Method: POST
- URL:
http://localhost:8080/wp-admin/post.php - Headers:
Content-Type: application/x-www-form-urlencoded - Body Parameters:
action:editpostpost_ID:[TARGET_POST_ID]_wpnonce:[EXTRACTED_NONCE]content:[the-subtitle before='<script>alert(1)</script>']post_title:XSS Test
6. Test Data Setup
- Plugin: Install and activate
kia-subtitleversion 4.0.1. - User: Create a user
attackerwith thecontributorrole. - Target Post:
wp post create --post_author=[ATTACKER_ID] --post_title="XSS Test" --post_status="publish" --post_content="Shortcode here"- Important:
wp post meta set [POST_ID] kia_subtitle "Valid Subtitle"(The shortcode only renders if a subtitle exists).
7. Expected Results
When any user (specifically an Administrator) navigates to the permalink of the created post:
- The WordPress engine parses the
[the-subtitle]shortcode. - The shortcode handler injects the raw
<script>tags into the page output. - The browser executes the JavaScript, resulting in an alert box showing
1.
8. Verification Steps
- Check Meta: Confirm the meta is set:
wp post meta get [POST_ID] kia_subtitle. - Verify Rendering: Use
http_request(GET) on the post URL and check if the raw payload exists in the source:grep "<script>alert(1)</script>"
- Confirm Sink: Ensure the script is not encoded as
<script>.
9. Alternative Approaches
If the before/after attributes are filtered by the WordPress KSES system during saving (unlikely for shortcodes), try bypassing via attribute breakout:
- Payload:
[the-subtitle before='<img src=x onerror=alert(1)>'] - If the site uses the Block Editor, try injecting the payload via the
kia/post-subtitleblock's attributes if they are mirrored in the shortcode implementation. However, the CVE specifically identifies the shortcode as the primary vector.
Summary
The KIA Subtitle plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'the-subtitle' shortcode's 'before' and 'after' attributes. Authenticated attackers with Contributor-level access can inject arbitrary web scripts into these attributes, which are then rendered without sanitization or escaping when the shortcode is processed.
Vulnerable Code
// kia-subtitle.php line 362 public function shortcode( $atts ) { $atts = shortcode_atts( array( 'before' => '<h2 class="subtitle">', 'after' => '</h2>' ), $atts, 'the-subtitle' ); $atts['echo'] = false; return $this->the_subtitle( $atts ); }
Security Fix
@@ -1 +1 @@ -<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-edit-post', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives'), 'version' => '3036d9bbf621acba6ed8'); +<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-edit-post', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives'), 'version' => '93e2c7f9267828be9f4d'); @@ -366,6 +366,8 @@ 'after' => '</h2>' ), $atts, 'the-subtitle' ); + $atts['before'] = wp_kses_post( $atts['before'] ); + $atts['after'] = wp_kses_post( $atts['after'] ); $atts['echo'] = false; return $this->the_subtitle( $atts );
Exploit Outline
The exploit target is the `[the-subtitle]` shortcode handler. An attacker with Contributor-level permissions (or higher) can create a post and set a value for the `kia_subtitle` custom field. By then inserting the shortcode `[the-subtitle before='<script>alert(1)</script>']` into the post content, the malicious script is stored in the WordPress database. When a user with higher privileges (like an Administrator) views the post on the frontend, the plugin concatenates the raw `before` attribute with the subtitle, causing the script to execute in the user's browser context.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.