SiYuan Bazaar Stored XSS via Unescaped Package Metadata Leading to Electron RCE
SiYuan's Bazaar marketplace fails to HTML-escape package `name` and `version` fields before rendering them to DOM via `innerHTML`, enabling stored XSS that escalates to OS command execution due to permissive Electron security configuration (nodeIntegration enabled, contextIsolation disabled).
CVE References
Affected
Vulnerability Description
This is a stored cross-site scripting (XSS) vulnerability in the package metadata rendering pipeline. The root cause is a gap in output encoding: the sanitizePackageDisplayStrings function in kernel/bazaar/package.go escapes Author, DisplayName, and Description fields but omits Name and Version. These unescaped strings are subsequently interpolated into HTML template literals (${item.preferredName}, ${data.name}, v${data.version}) and assigned directly to innerHTML in app/src/config/bazaar.ts, causing the browser parser to execute any embedded HTML/JavaScript. A secondary code path exists where displayName falls back to the unescaped pkg.Name when the locale map is empty, widening the attack surface.
PoC Significance & Reliability
The PoC demonstrates zero-click stored XSS: opening the Marketplace tab and viewing the Downloaded plugins list is sufficient to trigger payload execution—no user interaction with Install/Update buttons is required. Payloads persist in the package metadata (plugin.json, theme.json, etc.) and are executed every time the marketplace UI renders. The precondition is that a malicious or compromised package must be in the Bazaar repository or reachable via package distribution, but once present, any user browsing the marketplace is vulnerable. Reliability is near 100% given the deterministic nature of innerHTML assignment.
Detection Guidance
Log indicators:
- Monitor
app/src/config/bazaar.tsfor calls toinnerHTMLwithout prior sanitization. - Watch for anomalies in
plugin.json,theme.json,template.json,widget.json, oricon.jsonfiles wherenameorversionfields contain HTML tag delimiters (<,>,script,iframe, event handlers likeonerror=). - Scan Bazaar repository metadata for packages with suspicious characters in name/version: regex patterns like
name: ".*[<>'\"].*"orversion: ".*[<>'\"].*". - Monitor Node.js child process spawning from Electron renderer contexts; XSS in this configuration grants direct access to
child_process. - Search endpoint logs for unusual marketplace queries or bulk downloads of packages with malformed metadata.
YARA signatures (metadata-level):
rule SiYuan_Bazaar_XSS_Payload {
strings:
$name_tag = /"name"\s*:\s*"[^"]*[<>'\"][^"]*"/ nocase
$version_tag = /"version"\s*:\s*"[^"]*[<>'\"][^"]*"/ nocase
$script = /script|onerror|onload|innerHTML/ nocase
condition:
any of them
}
Mitigation Steps
- Immediate patch: Update
kernel/bazaar/package.goto escapeNameandVersioninsanitizePackageDisplayStrings; apply the same HTML entity encoding used forAuthorandDescription. - Frontend hardening: Replace
innerHTMLassignments withtextContentfor all package metadata fields, or use DOM methods likedocument.createTextNode()andappendChild(). - Electron security: Set
nodeIntegration: false,contextIsolation: true, andwebSecurity: trueinapp/electron/main.js:407-411(breaking change, requires preload script refactoring). - Input validation: Reject or strip package metadata containing HTML/XML-like syntax at ingestion into the Bazaar.
- Content Security Policy (CSP): Implement a strict CSP header preventing inline script execution and restricting Node.js API access from renderer context.
- Repository audit: Scan all existing packages in Bazaar for malicious payloads in
nameandversionfields.
Risk Assessment
Likelihood of exploitation in the wild: High. Bazaar is a public, community-driven marketplace; attackers can upload or compromise packages to distribute payloads. The zero-click nature and permissive Electron configuration make this low-friction for mass exploitation. Threat actor interest: Critical. This is a supply-chain attack vector enabling arbitrary code execution under the user's account with persistent payload storage. Advanced persistent threat (APT) actors, ransomware operators, and data-exfiltration groups would find this highly valuable. No user interaction required beyond opening a UI tab, making it suitable for automated worm-like distribution. The window for exploitation remains open until all users patch and Bazaar contents are sanitized.
Sources