Aug 25, 2026·6 min read·1 visit
A validation bypass in Plate's media component allows unauthenticated DOM-based XSS when rendering crafted document nodes.
CVE-2026-55596 is a critical DOM-based Cross-Site Scripting (XSS) vulnerability in the Plate rich-text editor framework (specifically within the @platejs/media package). The issue stems from an optimization fast-path that short-circuits safety parsing if a provider or source URL is already declared on an element. Consequently, serialized documents carrying malicious javascript: URLs bypass protocol sanitization and are loaded directly into iframe elements, leading to code execution.
The @platejs/media package is an essential module of the Plate rich-text editor, providing the structural capabilities to render, embed, and interact with external media components. The core rendering mechanism relies on parsing incoming URLs to display media players inside embedded document frameworks. By trusting serialized metadata without subsequent path verification, the software introduces a critical security vulnerability within client-side content processing.\n\nThis vulnerability is classified as Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79). The vulnerability presents a direct attack surface for DOM-based Cross-Site Scripting (XSS). An attacker can exploit this weakness by embedding arbitrary client-side script payloads within a formatted document representation.\n\nBecause Plate is designed to parse and load documents in various enterprise platforms, the vulnerability has extensive operational reach. Untrusted input parsed through the media components executes directly in the victim's active web session. Consequently, the flaw compromises the confidentiality and integrity of web sessions utilizing the rich-text framework.
The root cause of CVE-2026-55596 resides in a short-circuit logic path inside the useMediaState hook located in packages/media/src/react/media/useMediaState.ts. To minimize processing latency for pre-saved files, the hook was designed to check for pre-existing metadata properties. If either element.provider or element.sourceUrl was populated, the component bypassed standard sanitization functions.\n\nThis optimization created a security disparity between standard user inputs and pre-serialized input structures. While interactive text entry triggered immediate parser-level protocol validation via parseMediaUrl, direct database loads or API integrations passed data directly into the renderer. An attacker could craft a raw JSON node possessing legitimate provider attributes along with a malicious URL.\n\nWhen the system parsed the crafted JSON, the condition if (element.provider || element.sourceUrl) resolved to true. The hook immediately returned the unverified URL, failing to delegate processing to the protocol whitelist checker. The rendering function received the raw, unsafe URL directly and mapped it to the iframe's source locator.
Analysis of the vulnerability requires evaluating the code path in useMediaState.ts before the patch was applied. The original structure evaluated incoming nodes to determine if they possessed metadata attributes. The following code segment illustrates the vulnerable logical check:\n\ntypescript\n// Packages/media/src/react/media/useMediaState.ts (Pre-patch)\nexport const useMediaState = ({\n urlParsers = [parseVideoUrl],\n}: {\n urlParsers?: EmbedUrlParser[];\n} = {}) => {\n // ...\n const embed = useMemo(() => {\n if (!url) return;\n\n if (\n !isUrl(url) &&\n !urlParsers.some((parser) => url.startsWith(parser.name))\n ) \n return;\n\n // VULNERABLE METADATA TRUST BYPASS\n if (element.provider || element.sourceUrl) {\n return {\n id: element.id,\n provider: element.provider,\n sourceUrl: element.sourceUrl,\n url,\n };\n }\n\n return parseMediaUrl(url, { urlParsers });\n }, [element.id, element.provider, element.sourceUrl, urlParsers, url]);\n};\n\n\nThe corresponding patch resolved this bypass by removing the optimization check entirely. This forces all documents, regardless of pre-computed provider status, to run through the validation function:\n\ndiff\n- if (element.provider || element.sourceUrl) {\n- return {\n- id: element.id,\n- provider: element.provider,\n- sourceUrl: element.sourceUrl,\n- url,\n- };\n- }\n-\n return parseMediaUrl(url, { urlParsers });\n- }, [element.id, element.provider, element.sourceUrl, urlParsers, url]);\n+ }, [urlParsers, url]);\n\n\nBy forcing every invocation to pass through parseMediaUrl(url, { urlParsers }), the framework guarantees that URI schemes are validated. If a non-whitelisted scheme such as javascript: is detected, the URL parsing engine rejects it, neutralizing the attack vector.
To exploit this vulnerability, an attacker must be able to write or modify a Plate-compatible serialized document. Since the user interface sanitizes interactive inputs, the attacker bypasses the frontend controls and transmits the payload directly via API. The attacker constructs a serialized node block mimicking a Vimeo element but carrying a script execution directive.\n\nmermaid\ngraph LR\n A["Attacker Payload: JSON Node"] -->|Saves via API| B[("Workspace Database")]\n B -->|Loads Document| C["useMediaState React Hook"]\n C -->|Reads pre-defined provider| D["Short-circuit validation"]\n D -->|Passes raw javascript URL| E["MediaEmbedElement iframe src"]\n E -->|Executes in victim browser| F["DOM-based XSS"]\n\n\nThe target payload must explicitly provide a recognized provider parameter alongside the malicious payload in the url parameter. An example structure is as follows:\n\njson\n{\n "type": "media_embed",\n "id": "exploit-node",\n "provider": "vimeo",\n "sourceUrl": "https://player.vimeo.com/video/76979871",\n "url": "javascript:parent.postMessage('plate-media-xss', '*')",\n "children": [{ "text": "" }]\n}\n\n\nWhen a victim accesses the document containing this payload, the victim's client browser parses the JSON document. The rendering component receives the bypass return values and establishes the iframe element. The document browser frame then loads the javascript: URL, executing the arbitrary payload under the administrative session.
The impact of a successful DOM-based Cross-Site Scripting attack is high, affecting confidentiality and integrity. Because the script executes directly within the origin of the hosting application, it inherits the permissions of the active user. Attackers can leverage this position to extract cookies, access web storage variables, or capture access tokens stored in local memory.\n\nIf the hosting application maintains administrative interfaces, the attacker can execute administrative API commands on behalf of the victim. This enables complete account takeover, modification of application configurations, or lateral movement into broader cloud systems. The absence of an active availability impact indicates the target server remains stable, but data confidentiality is compromised.\n\nWith a CVSS Base Score of 8.7, this vulnerability demands immediate mitigation across all affected deployments. Because the attack requires low privileges and low complexity, any user with permission to contribute text to a workspace can deploy the malicious payload. This raises the likelihood of targeted internal compromise in multi-tenant environments.
The primary remediation path requires upgrading the @platejs/media package to version 53.1.4 or later. This release removes the vulnerable fast-path and establishes rigorous sanitization as a mandatory pipeline step. Development teams should audit package lockfiles to confirm transitive dependencies are updated appropriately.\n\nIf immediate dependency upgrades are not feasible due to release cycles, teams can construct a safe rendering wrapper. A custom component must intercept incoming url values and validate the protocols before passing them to the editor's original component. The following code block demonstrates a potential defensive wrapper implementation:\n\ntypescript\nimport React from 'react';\nimport { MediaEmbedElement } from '@platejs/media';\n\nexport const SanitizedMediaEmbed = (props: any) => {\n const { element } = props;\n const unsafeProtocolRegex = /^(javascript|data|vbscript):/i;\n\n if (unsafeProtocolRegex.test(element?.url)) {\n return <div className=\"media-placeholder\">Unsafe URL Blocked</div>;\n }\n\n return <MediaEmbedElement {...props} />;\n};\n\n\nIn addition to frontend overrides, implementing API-level ingestion sanitization provides defense-in-depth protection. Applications should validate document nodes during database ingestion, stripping any schema properties matching unauthorized schemes. This prevents the persistence of malicious payloads inside the backend storage systems.
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
@platejs/media udecode | >= 53.0.0, < 53.1.4 | 53.1.4 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-79 |
| Attack Vector | Network |
| CVSS Score | 8.7 |
| EPSS Score | 0.0043 |
| Exploit Status | poc |
| KEV Status | Not Listed |
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
A Server-Side Template Injection (SSTI) leading to Remote Code Execution (RCE) was discovered in the mcp-contextforge-gateway package before version 1.0.0. The vulnerability stems from an unsandboxed Jinja2 template rendering environment combined with an unsafe fallback mechanism using Python's native str.format() function. Attackers with template modification access could bypass static regex filters to execute arbitrary commands on the hosting platform.
The npm package 'pickem' is vulnerable to a terminal escape-sequence injection (CWE-150). Unsanitized terminal outputs allow attackers to execute arbitrary shell commands via clipboard hijacking (OSC 52) or manipulate terminal displays through Control Sequence Introducers (CSI).
CVE-2026-55537 is a server-side request forgery (SSRF) and time-of-check time-of-use (TOCTOU) vulnerability in the PraisonAI multi-agent framework before version 4.6.58. The flaw exists in the job-submission component's webhook URL validation logic. When DNS resolution fails during verification, the application fails open, enabling attackers to register unresolvable URLs. When a completed job triggers the webhook, the application performs a fresh DNS resolution that attackers can manipulate to target internal resources.
Prior to version 5.0.8, django CMS fails to respect dynamically declared Vary HTTP headers in its internal page cache. This allows remote attackers to bypass authorization, leak sensitive information across user sessions, or poison the page cache by sending requests with custom headers.
A security vulnerability in the github.com/gorilla/websocket Go library allows remote attackers to predict client-to-server frame masking keys. This occurs because the library generates 32-bit mask keys using Go's non-cryptographically secure pseudo-random number generator (math/rand). Predicting these keys enables adversaries to bypass proxy-based security protections, facilitating HTTP request smuggling and cache poisoning attacks.
MHSanaei 3X-UI is a web control panel for managing Xray-core servers. In versions prior to 3.3.1, an authenticated administrator can abuse database import functions or raw template config fields to overwrite or append to arbitrary files on the host filesystem. This is achieved by altering the Xray log configuration variables to target system files, leveraging logging components to inject payloads.