CVE-2026-31807: Github.com/siyuan note/siyuan/kernel Cross-Site Scripting Vulnerability
MODERATECVE-2026-31807 is a MODERATE cross-site scripting vulnerability (CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')) affecting Github.com/siyuan note/siyuan/kernel libraries in the Go ecosystem. The issue involves siyuan has a svg sanitizer bypass via `<animate>` element — unauthenticated xss. Remediation is available by upgrading affected packages to version 0.0.0-20260310025236-297bd526708f.
CVE-2026-31807 at a Glance
How to Fix CVE-2026-31807
To remediate this vulnerability, upgrade all affected Github.com/siyuan note/siyuan/kernel dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
Upgrade github.com/siyuan-note/siyuan/kernel to 0.0.0-20260310025236-297bd526708f
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
inspect dependencies for github.com/siyuan-note/siyuan/kernel
How to Check if You Are Affected
To determine whether your application is affected by CVE-2026-31807, inspect your project dependencies for Github.com/siyuan note/siyuan/kernel:
inspect dependencies for github.com/siyuan-note/siyuan/kernel
Analyze the terminal output to locate any version of Github.com/siyuan note/siyuan/kernel in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.0.0-20260310025236-297bd526708f), your application is affected.
Note: Verify declared build manifests and deployed runtime container environments.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting'), where the product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users. In Github.com/siyuan note/siyuan/kernel, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-31807 Affected Github.com/siyuan note/siyuan/kernel Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
github.com/siyuan-note/siyuan/kernel
|
Go |
< 0.0.0-20260310025236-297bd526708f
|
0.0.0-20260310025236-297bd526708f
|
References
Frequently Asked Questions
What is CVE-2026-31807?
Which Github.com/siyuan note/siyuan/kernel versions are affected?
What version fixes CVE-2026-31807?
Is github.com/siyuan-note/siyuan/kernel affected?
What CWE is associated with CVE-2026-31807?
How can I check Go dependencies for CVE-2026-31807?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-5hc8-qmg8-pw27",
"modified" : "2026-03-10T23:49:23Z",
"published" : "2026-03-10T23:49:23Z",
"aliases" : [ "CVE-2026-31807" ],
"summary" : "SiYuan has a SVG Sanitizer Bypass via `<animate>` Element — Unauthenticated XSS",
"details" : "# SVG Sanitizer Bypass via `<animate>` Element — Unauthenticated XSS\n\n## Summary\n\nSiYuan's SVG sanitizer (`SanitizeSVG`) blocks dangerous elements (`<script>`, `<iframe>`, `<foreignobject>`) and removes `on*` event handlers and `javascript:` in `href` attributes. However, it does NOT block SVG animation elements (`<animate>`, `<set>`) which can dynamically set attributes to dangerous values at runtime, bypassing the static sanitization. This allows an attacker to inject executable JavaScript into the unauthenticated `/api/icon/getDynamicIcon` endpoint (type=8), creating a reflected XSS.\n\nThis is a bypass of the fix for CVE-2026-29183 (fixed in v3.5.9).\n\n## Affected Component\n\n- **File:** `kernel/util/misc.go`\n- **Function:** `SanitizeSVG()` (lines 234-319)\n- **Endpoint:** `GET /api/icon/getDynamicIcon?type=8&content=...` (unauthenticated)\n- **Version:** SiYuan <= 3.5.9\n\n## Root Cause\n\nThe sanitizer checks attributes on elements at **parse time**. SVG `<animate>` and `<set>` elements modify attributes **at runtime** — these elements are not in the sanitizer's blocklist.\n\n### Sanitizer's blocklist (line 250)\n\n```go\nif tag == \"script\" || tag == \"iframe\" || tag == \"object\" || tag == \"embed\" || tag == \"foreignobject\" {\n n.RemoveChild(c)\n // ...\n}\n```\n\nMissing from blocklist: `animate`, `set`, `animateTransform`, `animateMotion`\n\n### Attribute check (lines 264-267)\n\n```go\n// Only checks static attributes\nif strings.HasPrefix(key, \"on\") {\n continue\n}\n```\n\nThe `<animate>` element's `values` attribute contains the payload (`javascript:...`), but the sanitizer only checks for `on*` prefix, `href`, or `xlink:href` keys. The `values`, `to`, `from`, `attributeName` attributes are all passed through.\n\n## Proof of Concept\n\n### Vector 1: `<animate>` sets `href` to `javascript:`\n\n```\nGET /api/icon/getDynamicIcon?type=8&content=</text><a><animate attributeName=\"href\" values=\"javascript:alert(document.domain)\" begin=\"0s\" fill=\"freeze\"/><text x=\"50%25\" y=\"80%25\" fill=\"red\" style=\"font-size:60px\">Click me</text></a><text>&color=blue\n```\n\nAfter template rendering, the SVG contains:\n```xml\n<svg ...>\n <text ...></text>\n <a>\n <animate attributeName=\"href\" values=\"javascript:alert(document.domain)\" begin=\"0s\" fill=\"freeze\"/>\n <text x=\"50%\" y=\"80%\" fill=\"red\" style=\"font-size:60px\">Click me</text>\n </a>\n <text></text>\n</svg>\n```\n\nThe sanitizer passes this through because:\n1. `<animate>` is not in the element blocklist\n2. `attributeName=\"href\"` — key is `attributename`, doesn't start with `on`, not `href` itself\n3. `values=\"javascript:...\"` — key is `values`, not `href`\n\nWhen the SVG is rendered in the browser (navigating directly to the URL), `<animate>` sets the parent `<a>` element's `href` to `javascript:alert(document.domain)`. Clicking \"Click me\" triggers the JavaScript.\n\n### Vector 2: `<set>` modifies event handlers\n\n```\nGET /api/icon/getDynamicIcon?type=8&content=</text><set attributeName=\"onmouseover\" to=\"alert(document.domain)\"/><text>&color=blue\n```\n\nThe `<set>` element dynamically adds an `onmouseover` event handler to the parent element at runtime.\n\n## Attack Scenario\n\n1. Attacker crafts a malicious `getDynamicIcon` URL with XSS payload\n2. Attacker sends the URL to a victim who has an active SiYuan session\n3. Victim clicks/navigates to the URL\n4. SVG renders with Content-Type `image/svg+xml` — browser renders as standalone SVG document\n5. JavaScript executes in the SiYuan server's origin\n6. Attacker steals session cookies, API tokens, or makes authenticated API calls to read/modify notes\n\n## Impact\n\n- **Severity:** CRITICAL (CVSS ~9.1)\n- **Type:** CWE-79 (Improper Neutralization of Input During Web Page Generation)\n- Unauthenticated reflected XSS via SVG injection\n- Executes in the SiYuan application origin, giving full access to authenticated APIs\n- Can chain to: data exfiltration, note modification, configuration theft (API tokens, auth codes)\n- Bypasses the fix for CVE-2026-29183\n\n## Suggested Fix\n\nAdd animation elements to the sanitizer blocklist:\n\n```go\n// In SanitizeSVG, line 250:\nif tag == \"script\" || tag == \"iframe\" || tag == \"object\" || tag == \"embed\" ||\n tag == \"foreignobject\" || tag == \"animate\" || tag == \"set\" ||\n tag == \"animatetransform\" || tag == \"animatemotion\" {\n n.RemoveChild(c)\n c = next\n continue\n}\n```\n\nOr additionally check the `values`, `to`, and `from` attributes for `javascript:` patterns:\n\n```go\nif key == \"values\" || key == \"to\" || key == \"from\" {\n if strings.Contains(val, \"javascript:\") {\n continue\n }\n}\n```\n\nAlso consider checking `attributeName` — if it targets `href`, `xlink:href`, or any `on*` attribute, the animation element should be removed entirely.",
"severity" : [ {
"type" : "CVSS_V4",
"score" : "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "Go",
"name" : "github.com/siyuan-note/siyuan/kernel"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "0.0.0-20260310025236-297bd526708f"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/siyuan-note/siyuan/security/advisories/GHSA-5hc8-qmg8-pw27"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-31807"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/siyuan-note/siyuan"
}, {
"type" : "WEB",
"url" : "https://github.com/siyuan-note/siyuan/releases/tag/v3.5.10"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-79" ],
"severity" : "MODERATE",
"github_reviewed" : true,
"github_reviewed_at" : "2026-03-10T23:49:23Z",
"nvd_published_at" : "2026-03-10T21:16:50Z"
}
}