SiYuan Affected by Stored XSS via Attribute View Name to Electron Renderer RCE
Date: 2026-05
Affected: go/github.com/siyuan-note/siyuan/kernel
Attack vector: xss
Category: vulnerability-disclosure
Severity: Critical
CVE: CVE-2026-44670
CWE: CWE-1188
CWE-79
CWE-94

## Summary The kernel stores Attribute View (AV / database) names without any HTML escape, then a render template uses raw `strings.ReplaceAll(tpl, "${avName}", nodeAvName)` to embed the name in HTML before pushing to all clients via WebSocket. Three independent client paths (`render.ts:120` → `outerHTML`, `Title.ts:401` → `innerHTML`, `transaction.ts:559` → `innerHTML`) consume the value without escaping. Because the main BrowserWindow runs `nodeIntegration:true, contextIsolation:false, webSecurity:false` (`app/electron/main.js:407-411`), HTML injection in the renderer becomes Node.js code execution. Payload is stored on disk under `data/storage/av/<id>.json`, replicates via every sync transport (S3 / WebDAV / cloud), survives `.sy.zip` export-import, and triggers for any role (Administrator / Editor / Reader / publish-service Visitor) opening a doc bound to the AV. ## Details **Kernel write — no escape.** `kernel/model/attribute_view.go:3244-3255`: ```go attrView.Name = strings.TrimSpace(operation.Data.(string)) attrView.Name = strings.ReplaceAll(attrView.Name, "\n", " ") if 512 < utf8.RuneCountInString(attrView.Name) { attrView.Name = gulu.Str.SubStr(attrView.Name, 512) } err = av.SaveAttributeView(attrView) // ← no html.EscapeString ``` **Kernel template — raw replace.** `kernel/model/attribute_view.go:3242,3283-3284`: ```go const attrAvNameTpl = `<span data-av-id="${avID}" ... class="popover__block">${avName}</span>` // ... tpl := strings.ReplaceAll(attr


Mitigations:

Architectural layers (MAESTRO):