You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A stored Cross-Site Scripting (XSS) vulnerability in SiYuan allows an attacker to inject arbitrary HTML attributes into the icon attribute of a block via the /api/attr/setBlockAttrs API. The payload is later rendered in the dynamic icon feature in an unsanitized context, leading to stored XSS and, in the desktop environment, potential remote code execution (RCE). This issue bypasses the previous fix for issue #15970 (XSS → RCE via dynamic icons).
Details
The /api/attr/setBlockAttrs endpoint accepts attacker-controlled data in the attrs.icon field:
Endpoint: POST /api/attr/setBlockAttrs
Parameter: attrs.icon
The value of icon is stored with the block and later used by the dynamic icon feature. When the icon is rendered, the string is inserted into HTML in an attribute context without proper escaping. By injecting a quote and a new attribute (e.g. onload), an attacker can execute arbitrary JavaScript whenever the affected block is rendered.
This reaches the same sink as the original dynamic icon issue reported in #15970 (XSS → RCE). The previous fix appears to constrain the UI path, but the same sink is still reachable via the backend API (setBlockAttrs), making this a bypass/regression of that fix.
Tested on: v3.4.2 .
Earlier versions are likely affected as long as they expose /api/attr/setBlockAttrs and the dynamic icon feature in the same way.
Replace <BLOCK_ID> with the ID of a block you can modify.
Send the request to the running SiYuan instance.
Open the UI and display the block with the modified icon.
When the dynamic icon is rendered, the injected onload attribute is executed and alert(document.domain) pops, demonstrating stored XSS.
The payload can be replaced with JavaScript that uses Node/Electron APIs (similar to #15970) to achieve RCE in the desktop application -> api/icon/getDynamicIcon\" onload=\"require('child_process').exec('gnome-calculator', null)
POC
Sxss-CVE-siyuan.mp4
Impact
Stored XSS: Any user who views the affected block triggers attacker-controlled JavaScript.
Desktop RCE: In the desktop app, the XSS can be escalated to arbitrary command execution via available Node/Electron/Electron-bridge APIs (same class of impact as #15970).
Attack prerequisites: Attacker must be able to reach the SiYuan API and modify a block’s attributes (directly via API, or indirectly via a feature that uses setBlockAttrs).
Given the potential for XSS → RCE in the desktop environment, this should be treated as a bypass/regression of #15970 and assigned its own CVE.
The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.
Learn more on MITRE.
Summary
A stored Cross-Site Scripting (XSS) vulnerability in SiYuan allows an attacker to inject arbitrary HTML attributes into the
iconattribute of a block via the/api/attr/setBlockAttrsAPI. The payload is later rendered in the dynamic icon feature in an unsanitized context, leading to stored XSS and, in the desktop environment, potential remote code execution (RCE). This issue bypasses the previous fix for issue#15970(XSS → RCE via dynamic icons).Details
The
/api/attr/setBlockAttrsendpoint accepts attacker-controlled data in theattrs.iconfield:POST /api/attr/setBlockAttrsattrs.iconThe value of
iconis stored with the block and later used by the dynamic icon feature. When the icon is rendered, the string is inserted into HTML in an attribute context without proper escaping. By injecting a quote and a new attribute (e.g.onload), an attacker can execute arbitrary JavaScript whenever the affected block is rendered.This reaches the same sink as the original dynamic icon issue reported in
#15970(XSS → RCE). The previous fix appears to constrain the UI path, but the same sink is still reachable via the backend API (setBlockAttrs), making this a bypass/regression of that fix.Tested on: v3.4.2 .
Earlier versions are likely affected as long as they expose
/api/attr/setBlockAttrsand the dynamic icon feature in the same way.PoC
<BLOCK_ID>with the ID of a block you can modify.When the dynamic icon is rendered, the injected
onloadattribute is executed andalert(document.domain)pops, demonstrating stored XSS.The payload can be replaced with JavaScript that uses Node/Electron APIs (similar to
#15970) to achieve RCE in the desktop application ->api/icon/getDynamicIcon\" onload=\"require('child_process').exec('gnome-calculator', null)POC
Sxss-CVE-siyuan.mp4
Impact
#15970).setBlockAttrs).Given the potential for XSS → RCE in the desktop environment, this should be treated as a bypass/regression of
#15970and assigned its own CVE.Reporter: 0xNayel
Solution
0be7e1d