CVE-2026-50551: SiYuan: Stored XSS to RCE via Unsanitized Attribute View Asset Cell Content
SiYuan v3.6.5 and earlier versions contain a stored cross-site scripting (XSS) vulnerability in the Attribute View (database) asset cell renderer that escalates to remote code execution (RCE) in the Electron desktop client. This is a neighbor-bug of CVE-2026-44588: the fix for -44588 used escapeAriaLabel() (double-escapes ${item.name item.content} ;
Published Jul 10, 2026
Affected packages
github.com/siyuan-note/siyuan/kernel
- Ecosystem
- Go
- Affected
- < 0.0.0-20260628153353-2d5d72223df4
- Fixed in
- 0.0.0-20260628153353-2d5d72223df4
- Check
go list -m github.com/siyuan-note/siyuan/kernel
Advisory details
From the GitHub Advisory Database (CC BY 4.0).
SiYuan v3.6.5 and earlier versions contain a stored cross-site scripting (XSS) vulnerability in the Attribute View (database) asset cell renderer that escalates to remote code execution (RCE) in the Electron desktop client. This is a neighbor-bug of CVE-2026-44588: the fix for -44588 used escapeAriaLabel() (double-escapes <), but the AV asset renderers were left using the weaker escapeAttr() (escapes only quotes) or no escaping at all.
Vulnerability Details
The Electron renderer is configured with nodeIntegration: true and contextIsolation: false (app/electron/main.js:307), allowing any JavaScript executing in the renderer to directly access Node.js APIs including require('child_process').
Two XSS sinks exist.
Sink 1 (Direct Stored XSS - triggers on page load)
app/src/protyle/render/av/cell.ts:1008:
text += ${item.name || item.content};
The >${item.name || item.content} portion is raw user input with zero escaping.
app/src/protyle/render/av/blockAttr.ts:93 (even worse - completely unescaped):
html += ``;
Rendered via action.ts:860: cellElement.innerHTML = renderCell(...) results in immediate XSS on page load.
Sink 2 (Hover-triggered XSS via aria-label round-trip)
- Same lines emit
aria-label="${escapeAttr(item.content)}"on.ariaLabelelements. escapeAttr()(util/escape.ts:14) escapes only"and'— NOT<or>.popover.ts:33global mouseover handler readsaria-labelviagetAttribute(which attribute-decodes entities).- Line 144:
showTooltip(decodeURIComponent(tip), ...)thentooltip.ts:41:messageElement.innerHTML = messageresults in XSS on hover.
Source
app/src/protyle/render/av/asset.ts:405:addAssetLink()reads user input from a free-form<textarea>with no sanitization.- Kernel stores
MAsset.Contentraw (kernel/av/value.go:53), no server-side sanitization.
Attack Vector
- Attacker creates a malicious note containing an Attribute View (database).
- Attacker adds an asset cell with link content: ``
- Victim opens the note for immediate RCE (Sink 1), or hovers over the cell for RCE (Sink 2).
- In a sync/collaboration scenario, the malicious note propagates to all users.
Proof of Concept
Payload (Direct XSS) — in an AV asset cell link field, enter:
For RCE in Electron desktop:
Steps to Reproduce
- Open SiYuan desktop app (v3.6.5).
- Create a new document.
- Insert an Attribute View (database):
/then select "Table". - Add a column of type "Asset".
- Click the asset cell, then "Add Link".
- In the "Link" textarea, paste: ``
- Leave "Title" empty or fill with benign text.
- Click outside the dialog to save.
- Observe: Alert fires immediately (Sink 1). Hovering over the cell also triggers (Sink 2).
Impact
- Remote Code Execution on victim's system via malicious note sync/import.
- Data exfiltration: attacker can read all notes, access filesystem, steal credentials.
- Persistence: malicious payload stored in
.syfiles, executes on every open.
Suggested Fix
- Replace
escapeAttr()withescapeAriaLabel()for allaria-labelattributes in AV cell renderers. - Escape
item.nameanditem.contentwithescapeHtml()before concatenating into element text content.
Affected files: app/src/protyle/render/av/cell.ts, app/src/protyle/render/av/blockAttr.ts, app/src/protyle/render/av/asset.ts.
Additional Context
This vulnerability is a neighbor-bug of CVE-2026-44588. The fix for -44588 correctly used escapeAriaLabel() (which double-escapes < to survive the attribute -> getAttribute -> innerHTML round-trip), but the AV asset cell renderers were left using the weaker escapeAttr() or no escaping. This is part of a pattern of incomplete fixes in SiYuan (see also CVE-2026-33066, CVE-2026-29183). The long-term fix should set ElectroncontextIsolation: true and nodeIntegration: false.
Report
Reporter (GitHub: Yunkaiwjs).
Credited to Yunkaiwjs.
References
How this page is made: the data panel comes from the GitHub Advisory Database, CISA’s KEV catalog, the NVD and FIRST EPSS, and updates twice a day. No analysis has been written for this entry yet. Methodology
More Go vulnerabilities
All Go entriesGHSA-p23f-cm6q-2qp8
SiYuan MCP asset.upload Reads Arbitrary Absolute File Paths (Workspace Boundary Bypass)
medium5.7Oct 2, 2026GHSA-x8gv-g2g3-65fj
SiYuan Agent Tools SSRF via DNS-Rebinding TOCTOU (Bypass of CheckHostSSRF)
high8.2Oct 2, 2026CVE-2026-69085
SiYuan: Unauthenticated SQL injection in searchDocs via unescaped keyword (publish mode): cross-notebook read/write with statement stacking
critical10.0Oct 1, 2026CVE-2026-69083
SiYuan: Unauthenticated SQL execution and REGEXP injection via fullTextSearchAssetContent (publish mode): reader-reachable raw SQL (method 2) and unescaped REGEXP (method 3) on read-write asset-content DB
critical10.0Sep 3, 2026CVE-2026-69084
SiYuan: Unauthenticated arbitrary SQL execution via searchEmbedBlock (publish mode) : reader-reachable raw statement on read-write handle, cross-notebook read/write
critical10.0Sep 3, 2026CVE-2026-72811
SiYuan: SQL injection in backlink/mention search via unescaped stored and client input (publish mode): first-order (client keyword) and second-order (stored document title) breakout on read-write handle
critical10.0Sep 3, 2026
