CVE-2026-55839: Kestra Stored XSS via Custom Markdown [[link]] Attribute Injection
A flaw in Kestra's custom Markdown renderer lets anyone who can write a Flow description inject JavaScript event handlers that execute in other users' browsers.
![CVE-2026-55839: Kestra Stored XSS via Custom Markdown [[link]] Attribute Injection](https://securelayer7.net/media/lab-ed0b530f.webp)
The problem
Kestra's Markdown renderer supports a custom [[link ...]] syntax that is converted into a <router-md> HTML element. The plugin in ui/src/utils/markdown_plugins/link.ts maps every parsed token attribute directly into the generated HTML string with no allowlist and no sanitization.
Any user who can create or edit a Flow can store a malicious payload in the Flow description field. When a second user opens the Flow list and views the description panel, the stored JavaScript runs in their browser under that user's session.
Proof of concept
A working proof-of-concept for CVE-2026-55839 in io.kestra:kestra, with the exact payload below.
[[link x="y" style="position:fixed;inset:0;z-index:9999;background:rgba(255,0,0,0.05)" onmouseover="alert(document.domain)"]]The vulnerable code path is straightforward. The renderer does token.attrs.map(([name, value]) => name+"="+value).join("") and drops the result raw into <router-md ${attrs}>. Nothing filters attribute names beginning with on, nothing rejects style, and nothing HTML-escapes values before the string reaches v-html.
The patch at commit 6c8e6d0 (v1.3.24) introduces an attribute allowlist so only the specific properties the router-md component actually needs are ever emitted. Arbitrary attributes, including all on* event handlers and style, are silently dropped before the HTML string is built.
This is CWE-79: unsanitized attacker input reflected into a rendered HTML context.
The fix
Upgrade to Kestra v1.3.24 or later. The fix is in commit 6c8e6d099ed172cbb6b003b7fb30b7bb1f8f710e: the [[link]] Markdown plugin now allowlists only the attributes the router component requires, rejects all on* event-handler attributes, rejects style, and HTML-escapes all attribute values before building the output string.
No workaround exists in older versions short of restricting Flow create/edit permissions to fully trusted users.
Related research
- high · 7.5OmniFaces: Forged Resource IDs, XSS via o:hashParam, and Push-Channel Replay
- highCVE-2026-69220CVE-2026-69220: RabbitMQ Java Client Uncontrolled Recursion DoS via Nested AMQP Tables
- highCVE-2026-69219CVE-2026-69219: RabbitMQ Java Client Unchecked LongString Allocation DoS
- highCVE-2026-63337CVE-2026-63337: RabbitMQ amqp-client Unsafe Reflection via JSON-RPC javaReturnType