May 8, 2026·5 min read·23 visits
Ech0 renders unescaped user input into its public RSS feed, permitting stored XSS attacks when users read the feed.
A stored Cross-Site Scripting (XSS) vulnerability exists in the Ech0 project's RSS feed generation component. The application fails to properly escape user-supplied tags and Markdown content before reflecting them in the `/rss` endpoint, allowing arbitrary JavaScript execution in vulnerable RSS readers.
The Ech0 application exposes an RSS and Atom feed endpoint at /rss to distribute content updates. This syndication component suffers from a stored Cross-Site Scripting (XSS) vulnerability. The flaw manifests when user-supplied input, specifically post content and associated tags, is incorporated into the XML response without adequate contextual output encoding or sanitization.
An attacker with permissions to create or modify content on the platform can inject arbitrary HTML or JavaScript payloads. When a user requests the feed or an RSS reader parses it, the injected payloads are reflected in the <summary type="html"> node. This reflection occurs continuously as long as the malicious post remains in the syndication queue.
This vulnerability represents a classic CWE-79 manifestation, specifically impacting downstream consumers of the syndication feed. The vulnerability assumes a moderate risk profile, as execution depends on the target RSS client honoring HTML rendering within the feed's summary tags.
The vulnerability is underpinned by two distinct rendering flaws in the application's Go source code. The first flaw resides in internal/service/common/common.go, where the GenerateRSS function constructs the feed summary.
The application appends dynamically generated tag names into the RSS feed using the fmt.Appendf function. The tag name string is passed via the %s format verb directly into a static HTML <span> container. Because no HTML escaping function is invoked on the tag name prior to string interpolation, standard HTML entity boundaries can be bypassed.
The second issue involves permissive rendering configuration in the gomarkdown library, located within internal/util/md/md.go. The MdToHTML utility invokes the renderer without specifying the html.SkipHTML flag. This omission instructs the parser to treat raw HTML tags embedded in Markdown as literal output rather than stripping them, thereby allowing direct script injection.
The patch applied in commit fd320fe3e9021c8d8d284fb274775c018690520e addresses both vectors through context-aware output encoding and input validation.
In the feed generation routine, the vulnerable implementation directly concatenated user input:
// Vulnerable
renderedContent = fmt.Appendf(
renderedContent,
"<br /><span class=\"tag\">#%s</span>",
tag.Name,
)The patched implementation wraps the tag name in stdhtml.EscapeString, preventing boundary breakouts:
// Patched
renderedContent = fmt.Appendf(
renderedContent,
"<br /><span class=\"tag\">#%s</span>",
stdhtml.EscapeString(tag.Name),
)Furthermore, the Markdown parsing configuration was hardened. The developer added html.SkipHTML to the Bitmask defining the renderer's standard flags, stripping raw HTML from parsed Markdown bodies. A defense-in-depth validation helper function, isSafeTagName, was also introduced in internal/service/echo/echo.go to reject tag names containing dangerous characters (<, >, ", ', &) during creation.
Exploitation requires the attacker to possess sufficient privileges to generate or modify an "echo" (post) or its associated tags. The attacker begins by submitting a payload designed to break out of the intended XML or HTML structure.
For the tag vector, an attacker creates a tag named </span><script>alert(1)</script>. For the Markdown vector, the attacker embeds a raw payload, such as <iframe src="javascript:alert(1)">, directly into the body of the post. The application stores this malicious content persistently in the backend database.
The execution phase triggers asynchronously when a victim subscribes to or views the /rss endpoint. An RSS reader that parses <summary type="html"> decodes the feed content and evaluates the unescaped script elements. The JavaScript executes within the security context of the domain hosting the feed or the local environment of the vulnerable client application.
The CVSS 3.1 base score of 5.3 reflects a moderate severity profile characterized by a low attack complexity but reliance on user interaction. The execution context determines the specific security impact.
If the victim views the feed through a web-based RSS reader hosted on the same domain as the application, the attacker gains the ability to hijack active sessions. The malicious script executes in the victim's browser context, enabling unauthorized API requests and access to sensitive user data.
When viewed through external or desktop RSS clients, the impact varies based on the client's internal rendering engine constraints. A client employing a hardened WebView minimizes direct exploitation, whereas less restrictive clients permit phishing, forced redirection to malicious infrastructure, or localized information disclosure.
Administrators must update their Ech0 deployments to a version incorporating commit fd320fe3e9021c8d8d284fb274775c018690520e. The patch natively resolves both root causes by applying strict output encoding and stripping raw HTML during markdown parsing.
If immediate patching is unfeasible, operators can deploy a Web Application Firewall (WAF) rule to inspect and block inbound requests attempting to submit HTML metacharacters to the post or tag creation endpoints. This prevents the initial storage of the payload.
Developers building upon similar syndication services must mandate strict output encoding for all user-controlled data placed into XML and HTML contexts. Employing structured templating engines with auto-escaping enabled by default prevents interpolation vulnerabilities inherent to standard string formatting functions.
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Ech0 lin-snow | All versions prior to fix commit fd320fe3 | fd320fe3e9021c8d8d284fb274775c018690520e |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-79 |
| Attack Vector | Network |
| CVSS Score | 5.3 |
| Impact | Stored Cross-Site Scripting |
| Exploit Status | Proof-of-Concept |
| Authentication Required | Yes (to post/tag) |
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
A high-severity access control vulnerability in ToolHive CLI before v0.30.1 and ToolHive Studio before v0.38.0 allows local containerized MCP servers to bypass network isolation. This enables malicious workloads to establish TCP/IP connections to administrative and control plane endpoints exposed on the host loopback interface.
AnyCable is a real-time communication server. Prior to version 1.6.15, its Pusher-compatible REST API suffered from an authentication bypass vulnerability because it failed to verify that the request body matched the signature-validated body_md5 parameter. This allows attackers to perform replay attacks with modified body contents.
A denial-of-service vulnerability exists in AnyIO prior to version 4.14.2. Standard error streams of process-pool workers are connected to an operating system pipe that is never drained by the parent process. This allows a worker to fill the pipe buffer and deadlock indefinitely.
CVE-2026-63349 is a critical privilege-dropping bypass vulnerability in the AnyIO asynchronous framework (versions 4.14.0 and 4.14.1) on POSIX platforms. Due to a variable assignment typo, supplementary groups specified by the developer are not correctly propagated to the execution backend, resulting in subprocesses retaining the parent process's elevated supplementary group permissions.
CVE-2026-63406 is an information disclosure vulnerability in AnyCable-go prior to version 1.6.15. The built-in telemetry client is enabled by default with a hardcoded public authentication token ('secret'). This client digests highly sensitive configuration parameters and command-line arguments, including JWT secrets and RPC secrets, into a stable SHA-256 fingerprint. This fingerprint is sent over public networks, exposing those administrative secrets to offline dictionary and brute-force attacks if intercepted.
CVE-2026-84992 is a Cross-Site Scripting (XSS) vulnerability affecting md-editor-v3 before version 6.5.4. It occurs because the fenced-code block language parser directly interpolates unescaped language metadata into unquoted HTML attributes inside the custom rendering callback. This bypasses the built-in XSSPlugin which runs during the parsing phase, before rendering.