CVE-2026-27458 - Stored XSS in Atom Feed via CDATA Escape in List Description
Author and Researcher

Ravindu Wickramasinghe
@rvz

1. Description
LinkAce v2.4.2 is vulnerable to stored cross-site scripting through the Atom feed endpoint for lists (/lists/feed). An authenticated user can inject a CDATA-breaking payload into a list description that escapes the XML CDATA section, injects a native SVG element into the Atom XML document, and executes arbitrary JavaScript directly in the browser when the feed URL is visited. No RSS reader or additional rendering context is required - the browser's native XML parser processes the injected SVG and fires the onload event handler.
This vulnerability exists because the lists feed template outputs list descriptions using Blade's raw syntax ({!! !!}) without sanitization inside a CDATA block. The v2.4.0 release patched the equivalent links feed template with strip_tags(), but the lists feed was overlooked. The critical detail is that because the output sits inside <![CDATA[...]]>, an attacker can inject the sequence ]]> to close the CDATA section prematurely, then inject arbitrary XML/SVG elements that the browser parses and executes natively as part of the Atom document.
Affected versions: LinkAce <= v2.4.2
Patched version: 2.5.2
2. Source Code Analysis
In resources/views/app/feed/links.blade.php, line 17 (patched in v2.4.0):
summary type="text" [CDATA[{ strip_tags($link->description) }]]summaryIn resources/views/app/feed/lists.blade.php, line 16 (unpatched):
summary type="html" [CDATA[{ $list->description }]]summaryWhen the payload is stored as a list description, the rendered Atom XML becomes:
<summary type="html"> <![CDATA[]]><svg xmlns="http://www.w3.org/2000/svg" onload="alert(document.domain)"/><![CDATA[]]></summary>The browser's XML parser sees: an empty CDATA section (<![CDATA[]]>), followed by a valid SVG element with an onload handler, followed by another empty CDATA section. The SVG element is parsed as a first-class XML node and its onload fires immediately.

3. Steps to Reproduce
- Log in to LinkAce as any authenticated user.
- Create a new list or edit an existing one.
- Set the list visibility to "Internal" or "Public".
- In the description field, enter the following CDATA escape payload:terminal
]]><svg xmlns="http://www.w3.org/2000/svg" onload="alert(document.domain)"/><![CDATA[ - Save the list.
- Open a browser and navigate to
/lists/feed. - The browser renders the Atom XML natively. The injected SVG element breaks out of the CDATA section and the
onloadhandler fires, displaying a JavaScript alert with the current domain. - For comparison, create a link with the same payload in its description and access
/links/feed- the links feed strips all HTML tags viastrip_tags()and does not execute.
4. CVSS
CVSS 4.0 Score: 8.7 (High)
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:N/SI:N/SA:N
5. Recommendations
The list description output in the feed template must be sanitized to prevent CDATA escape. At minimum, apply strip_tags() to match the existing links feed fix, changing line 16 of resources/views/app/feed/lists.blade.php from {!! $list->description !!} to {!! strip_tags($list->description) !!}, and change the summary type attribute from html to text.
However, strip_tags() alone does not neutralize CDATA escape sequences. A more robust fix should also escape or remove the literal string ]]> from any user content rendered inside CDATA blocks, or use htmlspecialchars() to entity-encode the output entirely. A review of all Blade templates using raw output syntax {!! !!} with user-controlled data inside CDATA sections should be conducted to identify additional instances.
