| Gói / sản phẩm | Phiên bản bị ảnh hưởng | Phiên bản đã vá |
|---|---|---|
| github.com/siyuan-note/siyuan/kernel | < 3.6.5mọi phiên bản | 3.6.5 |
The fix for CVE-2026-30869 in SiYuan v3.5.10 only added a denylist check (IsSensitivePath) but did not address the root cause — a redundant url.PathUnescape() call in serveExport(). An authenticated attacker can use double URL encoding (%252e%252e) to traverse directories and read arbitrary workspace files including the full SQLite database (siyuan.db), kernel log, and all user documents.
In kernel/server/serve.go, the serveExport() function (line 314-320) processes file paths as follows:
filePath := strings.TrimPrefix(c.Request.URL.Path, "/export/")
decodedPath, err := url.PathUnescape(filePath) // second decode
fullPath := filepath.Join(exportBaseDir, decodedPath)
Go's HTTP server already decodes percent-encoded characters once during request parsing. The additional url.PathUnescape() call creates a double-decode vulnerability:
GET /export/%252e%252e/siyuan.db%25 → %, result: URL.Path = /export/%2e%2e/siyuan.db%2e%2e as literal characters (not ..), no redirect occursurl.PathUnescape("%2e%2e") decodes to ..filepath.Join(exportBaseDir, "../siyuan.db") resolves to <workspace>/temp/siyuan.dbThe CVE-2026-30869 fix added IsSensitivePath() which blocks <workspace>/conf/ and OS-level paths (/etc, /root, etc.). However, it does NOT block:
<workspace>/temp/siyuan.db — full document database<workspace>/temp/blocktree.db — block tree database<workspace>/temp/siyuan.log — kernel log<workspace>/temp/asset_content.db — asset content databaseNote: the /appearance/ handler in the same file correctly uses gulu.File.IsSubPath() to validate paths (line 447), but this check is missing from the /export/ handler.
poc.zip Please extract the uploaded compressed file before proceeding
Bạn đang dùng một trong các sản phẩm này? Quét site để biết có đang lộ phiên bản có lỗ hổng không.
Quét site miễn phísiyuan.log) leaks internal server paths, versions, configuration details, and error messages.