CVE-2026-11380: Verified Reproduction
CVE-2026-11380: JetWidgets For Elementor Stored XSS via Animated Box animation effect
CVE-2026-11380 is verified against the affected target. Vulnerability class: XSS. This medium reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00203.
What Is CVE-2026-11380?
CVE-2026-11380 is a medium-severity stored cross-site scripting (XSS) vulnerability in the JetWidgets For Elementor WordPress plugin (versions up to and including 1.0.21), in the Animated Box widget's animation_effect setting. Pruva reproduced it (reproduction REPRO-2026-00203).
CVE-2026-11380 Severity & CVSS Score
CVE-2026-11380 is rated medium severity, with a CVSS base score of 6.4 out of 10.
Medium — meaningful risk under specific conditions. Schedule a fix in the normal cycle.
How to Reproduce CVE-2026-11380
pruva-verify REPRO-2026-00203 curl -O https://www.pruva.dev/api/v1/reproductions/REPRO-2026-00203/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh Proof of Reproduction for CVE-2026-11380
- reached the target end-to-end
- on the real production code path
- high confidence
- the upstream fix blocks the same trigger
animation_effect widget setting containing a double-quote that closes the class attribute and injects onmouseover/style attributes
- Published WordPress page rendered by Elementor + JetWidgets Animated Box widget
How the agent worked
Root Cause and Exploit Chain for CVE-2026-11380
The JetWidgets For Elementor WordPress plugin (versions up to and including 1.0.21) is vulnerable to a stored cross-site scripting (Stored XSS) flaw in the Animated Box widget. The widget's animation_effect setting is printed directly into the HTML class attribute of the rendered widget without output escaping or server-side validation. An attacker who can supply a value containing a double quote can break out of the class attribute and inject arbitrary attributes, including event handlers such as onmouseover="alert(1)". Because the payload is stored in the page and rendered whenever anyone visits the page, this is a stored XSS issue. The reproduction confirmed the payload in the published page HTML by deploying a real WordPress + Elementor + JetWidgets stack and viewing the rendered page.
- Product / component:
jetwidgets-for-elementor(Crocoblock / jetmonsters) — specifically thejw-animated-boxwidget. - Affected versions: 1.0.21 and earlier (the WordPress.org repository still lists 1.0.21 as the current stable release at the time of the CVE).
- Risk level: Medium. The vendor/Wordfence CVSS is reported as 6.4.
- Consequences: Any authenticated user with at least the
authorrole can save a page containing a malicious Animated Box widget. The injected JavaScript is stored in the page and executes in the browser of any visitor who views the page.
Impact Parity
- Disclosed / claimed maximum impact: Stored XSS via an author-level account in the Animated Box widget's
animation_effectsetting. - Reproduced impact from this run: A real WordPress environment was deployed with Elementor and JetWidgets 1.0.21. A published page was created with a malicious
animation_effectvalue. The rendered page HTML contains the escaped attribute boundary break and the injectedstyleandonmouseover="alert(1)"attributes. - Parity:
full— the reproduction reaches the same rendered-page sink described in the advisory. - Not demonstrated: The reproduction does not run a full browser engine, so the JavaScript payload itself is not executed in the test environment. The proof relies on the presence of the injected event handler in the server-rendered HTML, which is the root cause of the stored XSS.
Root Cause
The vulnerability is in the widget's render template:
<!-- templates/jw-animated-box/global/index.php (v1.0.21) -->
<div class="jw-animated-box <?php $this->__html( 'animation_effect', '%s' ); ?>">
The helper method chain ends up in includes/base/class-jet-widgets-base.php:
public function __render_html( $setting = null, $format = '%s' ) {
...
printf( wp_kses_post( $format ), $val );
}
wp_kses_post() is applied to the format string '%s', not to the value. Therefore the raw animation_effect value is printed verbatim inside the HTML class attribute. The UI control in includes/addons/jet-widgets-animated-box.php is a <select> with a fixed set of animation effects, but the server never validates the stored value before rendering it. A malicious author can supply a value such as:
jw-box-effect-1" style="position:fixed;width:100%;height:100%;top:0;left:0" onmouseover="alert(1)" data-x="
The first double quote closes the class attribute, the injected style covers the viewport, and the onmouseover handler will execute when a visitor moves the mouse over the page.
The vendor fixed the issue in commit 49952dd92b2bbd59e6627e7b67b0b3621c3852a0 (released as 1.0.22). The fix:
- Introduces a server-side
sanitize_animation_effect()method that rejects any value not in the allowed list of animation effects and falls back to the default. - Updates the template to use
esc_attr()on the sanitized value:
$animation_effect = $this->sanitize_animation_effect( $this->get_settings_for_display( 'animation_effect' ) );
?>
<div class="jw-animated-box <?php echo esc_attr( $animation_effect ); ?>">
Reproduction Steps
The full reproduction is automated by bundle/repro/reproduction_steps.sh. At a high level the script:
- Creates a Docker network and starts a
mysql:8.0container and awordpress:6.7-php8.1-apachecontainer. - Waits until the WordPress install page is reachable inside the Docker network.
- Installs WP-CLI, completes WordPress core installation, and sets the site URL to the internal Docker hostname (
http://jetwidgets-repro-wp). - Installs and activates Elementor 3.27.5 and JetWidgets For Elementor 1.0.21.
- Creates an
authorrole user. - Runs a PHP script inside the WordPress container that inserts a published page containing an Elementor
jw-animated-boxwidget whoseanimation_effectsetting is the malicious payload. - Fetches the rendered page from inside the Docker network using
curland copies the body and headers tobundle/repro/artifacts/. - Checks that the rendered HTML contains
onmouseover="alert(1)"and the injectedstyleattribute.
Expected evidence of reproduction: bundle/repro/artifacts/page.html contains a line similar to:
<div class="elementor-jw-animated-box jet-widgets"><div class="jw-animated-box jw-box-effect-1" style="position:fixed;width:100%;height:100%;top:0;left:0" onmouseover="alert(1)" data-x="">
Evidence
bundle/logs/reproduction_steps.log— step-by-step console output from the reproduction run.bundle/logs/insert.log— page ID and permalink produced by the PHP insertion script.bundle/logs/wordpress.log— Apache/WordPress container logs.bundle/logs/mysql.log— MySQL container logs.bundle/repro/artifacts/page.html— full HTML body of the rendered published page.bundle/repro/artifacts/page.headers— HTTP response headers from the page request.bundle/repro/artifacts/insert_page.php— the PHP helper used to create the malicious page.
Key excerpt from bundle/repro/artifacts/page.html (line 229 in the reproduced output):
<div class="elementor-jw-animated-box jet-widgets"><div class="jw-animated-box jw-box-effect-1" style="position:fixed;width:100%;height:100%;top:0;left:0" onmouseover="alert(1)" data-x="">
This shows that the animation_effect value broke out of the class attribute and added new attributes, including the onmouseover event handler.
Environment details captured in the runtime manifest:
- WordPress 6.7 (PHP 8.1 / Apache)
- Elementor 3.27.5
- JetWidgets For Elementor 1.0.21
- MySQL 8.0
Recommendations / Next Steps
- Upgrade: Site owners should upgrade JetWidgets For Elementor to version 1.0.22 or later, which contains commit
49952dd92b2bbd59e6627e7b67b0b3621c3852a0. - Fix approach:
- Server-side validation: reject any
animation_effectvalue that is not in the defined list of allowed effects (e.g.,jw-box-effect-1throughjw-box-effect-8). - Output escaping: render the value with
esc_attr()before placing it inside the HTMLclassattribute.
- Server-side validation: reject any
- Testing recommendations:
- Add unit/integration tests that save payloads containing
",<,>, andjavascript:in theanimation_effectsetting and assert that the rendered HTML does not contain an unescaped attribute break or event handler. - Test with the Elementor editor save flow as well as direct post-meta injection to ensure both paths are sanitized.
- Add unit/integration tests that save payloads containing
- Further verification: The script could be extended to include a real browser engine (e.g., Playwright/Chromium) to demonstrate actual JavaScript execution on mouseover. The current proof is sufficient to confirm the server-side sink but not a live browser exploit.
Additional Notes
- Idempotency: The reproduction script was executed twice consecutively from a clean state and succeeded both times. It cleans up all Docker containers and networks on exit via a
trap. - Limitations: The reproduction does not exercise the Elementor editor UI or the
admin-ajax.phpsave endpoint. It sets the widget data directly in post meta. This is acceptable for proving the rendered-page vulnerability sink, but it does not reproduce the full author-workflow UI. The root cause is the same regardless of how the malicious value reaches the database. - No custom exploit code: The reproduction uses the real WordPress, Elementor, and JetWidgets plugin code; no reimplementation of the vulnerability was used.
CVE-2026-11380 Reproduction Transcript
The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.
Full session Replay every step — scrub the timeline or play it back.
Artifacts and Evidence for CVE-2026-11380
Scripts, logs, diffs, and output captured during the reproduction.
How to Fix CVE-2026-11380
FAQ: CVE-2026-11380
How does the CVE-2026-11380 stored-XSS attack work?
animation_effect to a value containing a double quote followed by an injected attribute such as onmouseover="alert(1)"; because the value is stored and rendered unescaped whenever the page loads, the injected script executes in the browser of any visitor who views that page.How severe is CVE-2026-11380?
Does exploiting CVE-2026-11380 require authentication?
How can I reproduce CVE-2026-11380?
animation_effect value and confirms the unescaped payload appears in the rendered page HTML.References for CVE-2026-11380
Authoritative sources for CVE-2026-11380 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.