CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-27902

Svelte 5 SSR XSS: When JSON Met HTML Comments

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 26, 2026·6 min read·76 visits

Executive Summary (TL;DR)

Svelte 5's SSR error handling failed to escape `-->` sequences when serializing errors into HTML comments. Attackers can trigger an error containing malicious payloads to break out of the comment and execute XSS. Fixed in 5.53.5.

A Cross-Site Scripting (XSS) vulnerability exists in Svelte 5 versions prior to 5.53.5. The flaw occurs during Server-Side Rendering (SSR) when the framework attempts to serialize error objects into HTML comments for client-side hydration. Because the serialization process relied solely on `JSON.stringify()` without escaping HTML comment delimiters, an attacker can inject a closing comment tag (`-->`) to break out of the comment context and execute arbitrary JavaScript in the victim's browser.

The Hook: Hydration and Its Discontents

Modern web frameworks have a love-hate relationship with the DOM. To make pages load fast, we use Server-Side Rendering (SSR) to spit out a full HTML page before the JavaScript bundle even wakes up. But once the JavaScript loads, it needs to 'hydrate' that static HTML—attach event listeners, build the virtual DOM, and figure out the state of the world.

Svelte 5, with its fancy new 'runes' system, handles this by embedding serialization markers directly into the HTML. When a component crashes during SSR (inside an error boundary), Svelte needs to tell the client: "Hey, something went wrong here, don't try to hydrate this part normally." To do this, it serializes the error object and stuffs it into an HTML comment. It's a clever trick—browsers ignore comments, so the layout doesn't shift until Svelte takes over.

But here's the problem with clever tricks: they often rely on assumptions. Svelte assumed that JSON.stringify() was safe enough to put inside an HTML comment. They forgot that the HTML parser and the JSON parser speak two very different languages, and in the gap between them, XSS lives.

The Flaw: A collision of Specifications

This vulnerability is a classic case of "Context Confusion." In the world of JSON, the characters < and > are just boring string literals. JSON.stringify({ "msg": "-->" }) returns {"msg":"-->"}. It's valid JSON. It's safe JSON.

However, in the brutalist architecture of HTML, the sequence --> is the End of Comment delimiter. It doesn't matter if it's inside quotes, inside brackets, or inside a JSON object. If the HTML parser is reading a comment and sees -->, the comment ends. Immediately. Right there.

So, when Svelte takes that valid JSON and drops it into <!-- [JSON] -->, the browser parses it until it hits the attacker's -->. The rest of the JSON string is then dumped into the DOM as raw, executable markup. The developer trusted JSON.stringify to sanitize data, but JSON.stringify isn't an HTML sanitizer. It protects against JavaScript syntax errors, not HTML structure injection.

The Code: The One-Liner That Killed Security

Let's look at the crime scene in Renderer.js. The vulnerable code was deceptively simple. It takes a transformed error object and pushes it into the output buffer wrapped in comments.

Vulnerable Code (Before):

// Inside the renderer logic
child.#out.push(`<!--${HYDRATION_START_FAILED}${JSON.stringify(transformed)}-->`);

See the issue? It's a straight template literal injection. If transformed contains -->, the comment breaks. The fix, implemented in version 5.53.5, acknowledges that we are crossing a boundary between data and markup. We can't just stringify; we must escape the delimiters.

Fixed Code (After):

static #serialize_failed_boundary(error) {
    var json = JSON.stringify(error);
    // Manually escape angle brackets to their unicode equivalents
    var escaped = json.replace(/>/g, '\\u003e').replace(/</g, '\\u003c');
    return `<!--${HYDRATION_START_FAILED}${escaped}-->`;
}

The fix is elegant. By converting < and > to \u003c and \u003e, the JSON remains valid (JSON parsers decode unicode escapes automatically), but the HTML parser no longer sees the structural characters that define tags or comments.

The Exploit: Breaking the Fourth Wall

To exploit this, we need a specific setup: a Svelte 5 application using SSR, an Error Boundary, and a way to force an error that contains user-controlled input. Imagine a blog engine where a user can define a custom title that gets processed by a component.

The Attack Chain:

  1. Injection: The attacker sets their profile name or input to: --> <script>alert(origin)</script> <!--.
  2. Trigger: The attacker visits a page where this input causes a rendering error (or they trigger one intentionally via a malformed state).
  3. Serialization: The server catches the error. It tries to save the state for hydration: <!--{"message":"--> <script>alert(origin)</script> <!--"}-->.
  4. Execution: The victim's browser parses the HTML.

Here is how the browser sees the payload:

The trailing <!-- in the payload cleans up the mess, turning the real closing }--> of the JSON into a harmless comment, preventing syntax errors that might alert the user (or the console logs) too early.

The Impact: Why Server-Side XSS Hurts More

This isn't just a client-side DOM XSS. This is Reflected XSS delivered via the initial server response. This distinction matters for a few reasons. First, it bypasses many client-side XSS filters that only look for malicious DOM manipulation after load. Second, because the payload arrives in the initial HTML document, it executes immediately—often before any client-side security frameworks or Content Security Policy (CSP) nonces might be fully hydrated or applied if they rely on JS to initialize (though a strict HTTP-header CSP would still block inline scripts).

If the application is an Admin Dashboard or a Social Platform using Svelte 5, this allows full account takeover. The attacker can steal HttpOnly-flagged cookies (if the XSS is used to proxy requests), read local storage, or perform actions as the victim. Given Svelte's popularity in modern, high-interactivity web apps, the attack surface is specific but high-value.

Mitigation: Patching the Leak

The remediation is straightforward: Update to Svelte 5.53.5 immediately. The Svelte team has patched the Renderer.js logic to handle the escaping natively.

If you cannot update (perhaps you are locked to a specific version for enterprise reasons), you must ensure that any custom error transformation logic sanitizes the input before Svelte sees it. However, this is risky. You would need to implement a transformError hook that recursively strips or escapes --> sequences from error messages. But let's be honest: you're going to miss an edge case. Just update the package.

> [!NOTE] > This vulnerability only affects apps using Server-Side Rendering (SSR). If you are building a pure Single Page App (SPA) where the backend only serves JSON APIs and the frontend is a static bundle, this specific injection path does not exist, as the DOM API used by the browser to create comments is not susceptible to delimiter collision in the same way raw HTML parsing is.

Official Patches

SvelteSvelte 5.53.5 Release Notes
GitHubGitHub Security Advisory

Fix Analysis (1)

Technical Appendix

CVSS Score
5.3/ 10
CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:P/VC:L/VI:N/VA:N/SC:H/SI:H/SA:N
EPSS Probability
0.04%
Top 86% most exploited

Affected Systems

Svelte Framework (npm package: svelte)

Affected Versions Detail

Product
Affected Versions
Fixed Version
Svelte
Svelte
>= 5.53.0, < 5.53.55.53.5
AttributeDetail
CWE IDCWE-79
Attack VectorNetwork
CVSS Score5.3 (Medium)
ImpactCross-Site Scripting (XSS)
Exploit StatusProof of Concept (PoC) Available
Patch StatusFixed in 5.53.5

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1059.007Command and Scripting Interpreter: JavaScript
Execution
CWE-79
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

Known Exploits & Detection

GitHubFunctional test cases in the fix commit demonstrate the PoC payload.

Vulnerability Timeline

Patch committed to Svelte repository
2026-02-25
Public advisory (GHSA) released
2026-02-26
CVE ID assigned
2026-02-26

References & Sources

  • [1]GHSA-qgvg-pr8v-6rr3
  • [2]NVD - CVE-2026-27902

More Reports

•26 minutes ago•CVE-2026-107377
7.5

CVE-2026-107377: Arbitrary File Write and Overwrite via Protobuf Weak Import Path Traversal in datamodel-code-generator

A path traversal vulnerability in datamodel-code-generator allows remote attackers to write or overwrite arbitrary files on the local host filesystem via a manipulated Protobuf schema containing malicious weak import paths.

Amit Schendel
Amit Schendel
2 views•5 min read
•about 1 hour ago•CVE-2026-61431
6.8

CVE-2026-61431: Arbitrary Local File Read and Path Traversal in PraisonAI ContextGatherer

PraisonAI is vulnerable to an arbitrary local file read vulnerability prior to version 4.6.78. The flaw is in the ContextGatherer component, where validation checks are executed only after files are parsed and appended to the context bundle, bypassing security constraints.

Amit Schendel
Amit Schendel
6 views•6 min read
•about 2 hours ago•CVE-2026-107212
7.5

CVE-2026-107212: CPU Exhaustion Denial of Service via Look-Ahead Row Parsing in Excelize

An algorithmic complexity vulnerability (CWE-770) in the Excelize library allows remote attackers to cause resource exhaustion (100% CPU usage) via a crafted Microsoft Excel spreadsheet. This occurs because the look-ahead row index parsing in Rows.Columns() fails to enforce upper boundary limits, enabling an out-of-bounds row index to trigger an infinite seek loop inside the Rows iterator.

Alon Barad
Alon Barad
10 views•6 min read
•about 3 hours ago•CVE-2026-105647
4.0

CVE-2026-105647: Server-Side Request Forgery via Favicon Probing in Ghost CMS

An unauthenticated Server-Side Request Forgery (SSRF) vulnerability exists in Ghost CMS from version 6.54.1 to 6.65.0. The vulnerability stems from a validation bypass in the favicon resolution logic within the bookmark-fetching subsystem, which allows remote, unauthenticated attackers to trigger arbitrary HTTP requests to the local host and internal networks. This bypass circumvents the custom DNS-level IP blocklist controls configured globally in the application.

Alon Barad
Alon Barad
7 views•8 min read
•about 4 hours ago•CVE-2026-106450
5.3

CVE-2026-106450: Denial of Service via Eager Resource Allocation in lz4-java LZ4FrameInputStream

A resource allocation vulnerability (CWE-770) in lz4-java before version 1.11.4 allows an unauthenticated remote attacker to trigger CPU exhaustion and high garbage collection overhead by streaming empty concatenated LZ4 frames.

Alon Barad
Alon Barad
12 views•8 min read
•about 5 hours ago•CVE-2026-106449
3.7

CVE-2026-106449: Stack Overflow via Uncontrolled Recursion in yawkat lz4-java

A Denial of Service (DoS) vulnerability exists in the yawkat fork of lz4-java prior to version 1.11.4. Under specific non-default configurations (stopOnEmptyBlock = false), parsing crafted streams with a large sequence of contiguous empty LZ4 blocks triggers uncontrolled recursion inside the LZ4BlockInputStream.refill() method, causing stack exhaustion and thread termination.

Alon Barad
Alon Barad
7 views•6 min read