Apr 1, 2026·6 min read·2 visits
A flaw in SiYuan's `SanitizeSVG` function allows attackers to bypass XSS filters using XML namespace prefixes (e.g., `<x:script>`). This enables unauthenticated remote code execution within the victim's browser context. The issue affects versions 3.6.0 to 3.6.1 and is fixed in 3.6.2.
SiYuan personal knowledge management system versions 3.6.0 through 3.6.1 contain a high-severity Reflected Cross-Site Scripting (XSS) vulnerability. The flaw exists in the SVG sanitization logic within the `/api/icon/getDynamicIcon` endpoint, where an attacker can bypass tag blocklists using XML namespace prefixes. Successful exploitation allows unauthenticated attackers to execute arbitrary JavaScript in the context of the victim's session.
The SiYuan personal knowledge management system exposes an unauthenticated API endpoint at /api/icon/getDynamicIcon designed to serve dynamic SVG icons to clients. This endpoint accepts user-controlled input, presumably base64-encoded or directly parameterized SVG data, and reflects it back to the requester. To prevent malicious code execution, the application routes the input through a custom SanitizeSVG function introduced in version 3.6.0.
This sanitization function contains a critical logic flaw classified under CWE-79 (Improper Neutralization of Input During Web Page Generation). The filter fails to account for XML namespace prefixes when evaluating HTML5/SVG node names. Consequently, an attacker can construct a payload that passes the backend validation but executes as a malicious script when parsed by the victim's browser.
The vulnerability requires user interaction to exploit, specifically requiring the victim to open a maliciously crafted URL pointing to the vulnerable SiYuan instance. Because the application serves the response with an image/svg+xml content type and lacks a restrictive Content Security Policy (CSP), the browser natively executes the embedded JavaScript. This grants the attacker full access to the application's DOM and the victim's active session.
The root cause of CVE-2026-34605 lies in a mismatch between how the backend Go HTML5 parser interprets SVG nodes and how a frontend browser's XML parser resolves them. The SanitizeSVG function processes incoming SVG data by parsing it into a node tree and walking the tree to filter out restricted tags. The security logic enforces a strict string matching algorithm, specifically targeting known dangerous elements like the <script> tag.
When the Go HTML5 parser encounters an element with an XML namespace prefix, such as <x:script xmlns:x="http://www.w3.org/2000/svg">, it records the node's tag name exactly as written: x:script. The sanitization routine subsequently compares this tag name against its blocklist. Since the literal string x:script does not equal script, the evaluation yields false, and the node is permitted to pass through the filter untouched.
Modern web browsers implement robust XML parsing engines that strictly adhere to W3C namespace specifications. When the browser receives the sanitized payload served with the image/svg+xml MIME type, it recognizes the xmlns:x attribute and resolves the x: prefix to the designated SVG namespace. The browser then strips the prefix during DOM construction, treating the element as a standard <script> tag and immediately executing its textual content as JavaScript.
The underlying defect is a classic parser differential. The backend relies on a simplistic string comparison that fails to normalize XML local names before evaluation. A conceptual representation of the vulnerable logic demonstrates the flaw:
// Vulnerable Conceptual Implementation
func SanitizeSVG(input string) string {
// Go HTML5 parser preserves the 'x:script' prefix
nodeName := extractNodeName(input)
// Blocklist explicitly checks for 'script' without stripping prefixes
if nodeName == "script" || nodeName == "iframe" || nodeName == "object" {
return removeNode(input)
}
return input
}To remediate this issue, the parsing logic must evaluate the local name of the element rather than the raw, prefixed tag name. The fix implemented in version 3.6.2 ensures that namespace prefixes are stripped or properly resolved before the blocklist comparison occurs. Alternatively, an allowlist approach strictly permitting only known-safe SVG structural elements entirely eliminates this class of bypass.
The following diagram illustrates the data flow of the exploit, demonstrating how the payload circumvents the backend filter but triggers execution in the frontend:
Exploitation of CVE-2026-34605 relies on delivering a crafted URL to an authenticated user of the targeted SiYuan instance. The attacker constructs an SVG payload containing the namespace-prefixed script tag. The payload definition establishes a custom namespace alias mapping back to the standard W3C SVG namespace.
The proof-of-concept payload demonstrates the required structural elements:
<svg xmlns="http://www.w3.org/2000/svg">
<x:script xmlns:x="http://www.w3.org/2000/svg">alert('CVE-2026-34605')</x:script>
</svg>The attacker typically base64-encodes or URL-encodes this payload depending on the specific parameter requirements of the getDynamicIcon endpoint. The resulting URL is distributed via phishing emails, direct messages, or embedded as a link in external forums. When the victim clicks the link, their browser issues a GET request to the vulnerable endpoint.
Because the endpoint is unauthenticated, the application processes the request regardless of the victim's session state. The server reflects the payload back to the client. If the victim has an active session within the SiYuan application on the same domain, the executed JavaScript gains full access to their session tokens, local storage, and the application's authenticated APIs.
The CVSS 4.0 assessment assigns this vulnerability a base score of 8.6, reflecting a High severity profile. The vector string CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:H/VI:H/VA:L/SC:N/SI:N/SA:N highlights the primary risk factors: network-based attack vector, low complexity, no authentication requirement, and high impact on confidentiality and integrity.
The confidentiality impact (VC:H) stems from the attacker's ability to exfiltrate sensitive data. The executed JavaScript can read the victim's personal knowledge base, extract session cookies, and capture CSRF tokens. This data is silently transmitted to an attacker-controlled server using standard web APIs like fetch or XMLHttpRequest.
The integrity impact (VI:H) is equally severe. An attacker can leverage the compromised session to manipulate the user's data. This includes modifying existing notes, deleting workspaces, or injecting persistent XSS payloads into the stored knowledge base, effectively upgrading a reflected XSS vulnerability into a stored XSS vector. The availability impact (VA:L) remains low, as the attack primarily targets user data rather than the underlying server infrastructure.
The primary and most effective remediation for CVE-2026-34605 is updating the SiYuan application to version 3.6.2 or later. The patch addresses the root cause by correcting the SVG sanitization logic to properly handle XML namespace prefixes, preventing the bypass condition.
For environments where immediate patching is not feasible, administrators must implement compensating controls. Deploying Web Application Firewall (WAF) rules to inspect incoming requests to the /api/icon/getDynamicIcon endpoint provides an effective temporary mitigation. The WAF should drop requests containing the xmlns attribute or namespace aliases (e.g., x:, ns1:) within the icon parameter payload.
Furthermore, implementing a strict Content Security Policy (CSP) provides architectural defense-in-depth against XSS vulnerabilities. Configuring the application to serve API responses with a CSP header that restricts script execution (e.g., default-src 'none') neutralizes the attack even if the backend parser fails to sanitize the payload. Administrators should also ensure the application configures the X-Content-Type-Options: nosniff header across all API endpoints.
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:H/VI:H/VA:L/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
SiYuan siyuan-note | >= 3.6.0, < 3.6.2 | 3.6.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-79 (Improper Neutralization of Input During Web Page Generation) |
| Attack Vector | Network |
| CVSS Score | 8.6 (High) |
| Impact | High Confidentiality, High Integrity |
| Exploit Status | Proof of Concept Available |
| KEV Status | Not Listed |
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')