Intelligence
highVulnerabilityActive

SiYuan SanitizeSVG Bypass via XML MIME Type Omission – Incomplete CVE-2026-29183 Fix

SiYuan's SVG sanitizer blocks data:text/html and data:image/svg+xml but misses data:text/xml and data:application/xml, allowing unauthenticated XSS via the /api/icon/getDynamicIcon endpoint. The fix for CVE-2026-29183 was incomplete, leaving equivalent bypass vectors.

S
Sebastion

CVE References

Affected

SiYuan/v3.6.0

Vulnerability Description

This is a Stored/Reflected XSS vulnerability arising from incomplete input sanitization. The root cause is a blocklist-based defense for SVG <a href> attributes that enumerates only three MIME types (data:text/html, data:image/svg+xml) rather than implementing a whitelist or rejecting all data: URIs by default. The content parameter in /api/icon/getDynamicIcon is embedded into SVG via string formatting without HTML entity escaping or URI validation. Because XML processing is enabled in browsers, both data:text/xml and data:application/xml trigger onload event handlers, achieving arbitrary JavaScript execution in the attacker's chosen context.

PoC Significance

The PoC demonstrates that the prior patch attempt failed due to incomplete threat modeling. It shows: (1) the endpoint is unauthenticated and publicly accessible, (2) the fmt.Sprintf embedding preserves attacker-controlled characters, (3) a minimal XML payload with onload executes reliably on Chromium 136+. The attack vector requires click-through or embedding via <object>/<embed> tags—not interactive when served as <img>—but remains viable if the endpoint URL is shared or if the icon system internally uses unsafe embedding methods. The PoC also validates that two additional MIME types bypass the filter, indicating the developers did not think through the full scope of data-URI schemes.

Detection Guidance

Log Indicators: Monitor for requests to /api/icon/getDynamicIcon with type=8 and content parameters containing data:text/xml, data:application/xml, data:text/plain, or other whitelisted MIME types that may render executable code. WAF Signatures: Block requests where the content parameter contains regex patterns like data:[a-z]+/[a-z+]+.*onload|onerror|onclick. Endpoint Monitoring: Flag any SVG responses from this endpoint containing <a> elements with href attributes pointing to data: URIs. Browser-level Detection: DOM-based XSS detectors in DevTools may flag injected onload handlers when the SVG is navigated to directly or embedded in unsafe contexts.

Mitigation Steps

  1. Immediate Patch: Update the SanitizeSVG function to reject all data: URIs in href attributes (not just three types). Use a whitelist model: only allow http:// and https:// schemes, with strict domain validation if internal links are needed.
  2. Input Escaping: Apply HTML entity encoding to the content parameter before embedding in SVG; use a dedicated SVG sanitization library (e.g., DOMPurify with SVG mode or bleach in Python).
  3. Content-Type Enforcement: Serve the endpoint response with X-Content-Type-Options: nosniff and Content-Security-Policy: default-src 'none'; style-src 'unsafe-inline' to constrain execution context.
  4. Authentication: Require authentication for /api/icon/getDynamicIcon or enforce strict rate-limiting if public access is essential.
  5. Testing: Add regression tests with payloads using all known data-URI MIME types (text/xml, application/xml, text/plain, application/json, etc.) to prevent similar bypasses.

Risk Assessment

Likelihood: Medium-to-High. The endpoint is unauthenticated and the bypass uses simple, predictable MIME type substitution—low barrier to exploitation. Threat Actor Interest: High for document collaboration platforms; SiYuan is a personal knowledge base, but if deployed in enterprise settings, stored XSS could lead to credential theft or lateral movement. Real-World Exploitation: Click-through attacks are less reliable than stored XSS, but the simplicity of crafting URLs and the lack of authentication lower the activation energy. Attackers may use this to embed malicious icons in shared notebooks or forums.