CVE-2026-31807

mediumpriority · track · 24EPSS 0.005 · 39 %ileEUUS
grimoire priorityP3 · Track
Exploitable?
—
no known exploitation
Likely / severe?
0.46% (39th) EPSS
CVSS 6.1 · medium
Is it mine?
3 products
Check your exposure
Who says so?
4 sources
cnnvd · enisa_euvd · osv · nvd

EPSS · scored 2026-10-27

SiYuan is a personal knowledge management system. Prior to 3.5.10, SiYuan'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. This is a bypass of the fix for CVE-2026-29183 (fixed in v3.5.9). This vulnerability is fixed in v3.5.10.

01

cvss

Technical severity, 0–10. One row per scoring source.

6.4
010

base score 0–10 · higher = more severe · hover a vector to decode

v3.16.1mediumCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:Nprimary · NVD / NIST USexploitability 2.8 · impact 2.7
v4.06.4mediumCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:H/SI:H/SA:Nsecondary · ENISA EU
v4.06.4mediumCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:Xsecondary · security-advisories@github.com
v4.05.4mediumCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:Xsecondary · CVSS-BT (t0sche)
02

ssvc

A stakeholder decision — act, attend, or track — from exploitation and impact.

Exploitation: none · Automatable: yes · Technical Impact: partialcoordinatorcisa_ssvcUS
03

weaknesses

The CWE weakness classes this flaw belongs to.

04

affected products (3)

Products and version ranges known to be affected.

05

advisories (2)

Vendor and ecosystem advisories describing this.

  • GHSA-5hc8-qmg8-pw27SiYuan has a SVG Sanitizer Bypass via `<animate>` Element — Unauthenticated XSS2026-03-10ghsa · osvUS

    # SVG Sanitizer Bypass via `<animate>` Element — Unauthenticated XSS ## Summary SiYuan'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. This is a bypass of the fix for CVE-2026-29183 (fixed in v3.5.9). ## Affected Component - **File:** `kernel/util/misc.go` - **Function:** `SanitizeSVG()` (lines 234-319) - **Endpoint:** `GET /api/icon/getDynamicIcon?type=8&content=...` (unauthenticated) - **Version:** SiYuan <= 3.5.9 ## Root Cause The 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. ### Sanitizer's blocklist (line 250) ```go if tag == "script" || tag == "iframe" || tag == "object" || tag == "embed" || tag == "foreignobject" { n.RemoveChild(c) // ... } ``` Missing from blocklist: `animate`, `set`, `animateTransform`, `animateMotion` ### Attribute check (lines 264-267) ```go // Only checks static attributes if strings.HasPrefix(key, "on") { continue } ``` The `<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. ## Proof of Concept ### Vector 1: `<animate>` sets `href` to `javascript:` ``` GET /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 ``` After template rendering, the SVG contains: ```xml <svg ...> <text ...></text> <a> <animate attributeName="href" values="javascript:alert(document.domain)" begin="0s" fill="freeze"/> <text x="50%" y="80%" fill="red" style="font-size:60px">Click me</text> </a> <text></text> </svg> ``` The sanitizer passes this through because: 1. `<animate>` is not in the element blocklist 2. `attributeName="href"` — key is `attributename`, doesn't start with `on`, not `href` itself 3. `values="javascript:..."` — key is `values`, not `href` When 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. ### Vector 2: `<set>` modifies event handlers ``` GET /api/icon/getDynamicIcon?type=8&content=</text><set attributeName="onmouseover" to="alert(document.domain)"/><text>&color=blue ``` The `<set>` element dynamically adds an `onmouseover` event handler to the parent element at runtime. ## Attack Scenario 1. Attacker crafts a malicious `getDynamicIcon` URL with XSS payload 2. Attacker sends the URL to a victim who has an active SiYuan session 3. Victim clicks/navigates to the URL 4. SVG renders with Content-Type `image/svg+xml` — browser renders as standalone SVG document 5. JavaScript executes in the SiYuan server's origin 6. Attacker steals session cookies, API tokens, or makes authenticated API calls to read/modify notes ## Impact - **Severity:** CRITICAL (CVSS ~9.1) - **Type:** CWE-79 (Improper Neutralization of Input During Web Page Generation) - Unauthenticated reflected XSS via SVG injection - Executes in the SiYuan application origin, giving full access to authenticated APIs - Can chain to: data exfiltration, note modification, configuration theft (API tokens, auth codes) - Bypasses the fix for CVE-2026-29183 ## Suggested Fix Add animation elements to the sanitizer blocklist: ```go // In SanitizeSVG, line 250: if tag == "script" || tag == "iframe" || tag == "object" || tag == "embed" || tag == "foreignobject" || tag == "animate" || tag == "set" || tag == "animatetransform" || tag == "animatemotion" { n.RemoveChild(c) c = next continue } ``` Or additionally check the `values`, `to`, and `from` attributes for `javascript:` patterns: ```go if key == "values" || key == "to" || key == "from" { if strings.Contains(val, "javascript:") { continue } } ``` Also consider checking `attributeName` — if it targets `href`, `xlink:href`, or any `on*` attribute, the animation element should be removed entirely.

  • GO-2026-4667SiYuan has a SVG Sanitizer Bypass via `<animate>` Element — Unauthenticated XSS in github.com/siyuan-note/siyuan/kernel2026-03-12vendor · osvUS

    SiYuan has a SVG Sanitizer Bypass via `<animate>` Element — Unauthenticated XSS in github.com/siyuan-note/siyuan/kernel

06

also known as (5)

Other names and identifiers for this entity.

07

sources

Which sources assert this record, and when.

published 2026-03-10modified 2026-06-17
08

references (4)

External citations — patches, advisories, analysis.

scry

Attackers weaponise vulnerabilities like this against internet-exposed services. See what is exposed on your perimeter with a free passive scan.

Free scan