High severity7.5OSV Advisory· Published Jan 19, 2026· Updated Apr 29, 2026
CVE-2026-23850
CVE-2026-23850
Description
SiYuan is a personal knowledge management system. In versions prior to 3.5.4, the markdown feature allows unrestricted server side html-rendering which allows arbitrary file read (LFD). Version 3.5.4 fixes the issue.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/siyuan-note/siyuan/kernelGo | < 0.0.0-20260118092326-b2274baba2e1 | 0.0.0-20260118092326-b2274baba2e1 |
Affected products
1- Range: dev2.0.17-2, v0.1.0, v0.1.1, …
Patches
2f8f4b517077b:lock: Arbitrary file reading vulnerability https://github.com/siyuan-note/siyuan/issues/16860
1 file changed · +1 −0
kernel/util/path.go+1 −0 modified@@ -416,6 +416,7 @@ func IsSensitivePath(p string) bool { "passwd": {}, "shadow": {}, "pgpass": {}, + "hosts": {}, "credentials": {}, // 如 aws credentials "config.json": {}, // docker config.json 可能含 token }
b2274baba2e1:lock: Arbitrary file reading vulnerability https://github.com/siyuan-note/siyuan/issues/16860
3 files changed · +118 −3
kernel/api/file.go+14 −2 modified@@ -66,14 +66,26 @@ func globalCopyFiles(c *gin.Context) { srcs = append(srcs, s.(string)) } - for _, src := range srcs { - if !filelock.IsExist(src) { + for i, src := range srcs { + absSrc, _ := filepath.Abs(src) + + if !filelock.IsExist(absSrc) { msg := fmt.Sprintf("file [%s] does not exist", src) logging.LogErrorf(msg) ret.Code = -1 ret.Msg = msg return } + + if util.IsSensitivePath(absSrc) { + msg := fmt.Sprintf("refuse to copy sensitive file [%s]", src) + logging.LogErrorf(msg) + ret.Code = -2 + ret.Msg = msg + return + } + + srcs[i] = absSrc } destDir := arg["destDir"].(string) // 相对于工作空间的路径
kernel/model/assets.go+12 −1 modified@@ -248,7 +248,18 @@ func netAssets2LocalAssets0(tree *parse.Tree, onlyImg bool, originalURL string, u = u[:strings.Index(u, "?")] } - if !gulu.File.IsExist(u) || gulu.File.IsDir(u) { + if !gulu.File.IsExist(u) { + logging.LogErrorf("local file asset [%s] not exist", u) + continue + } + + if gulu.File.IsDir(u) { + logging.LogWarnf("ignore converting directory path [%s] to local asset", u) + continue + } + + if util.IsSensitivePath(u) { + logging.LogWarnf("ignore converting sensitive path [%s] to local asset", u) continue }
kernel/util/path.go+92 −0 modified@@ -347,3 +347,95 @@ func IsPartitionRootPath(path string) bool { return cleanPath == "/" } } + +// IsSensitivePath 对传入路径做统一的敏感性检测。 +func IsSensitivePath(p string) bool { + if p == "" { + return false + } + pp := filepath.Clean(strings.ToLower(p)) + + // 精确敏感文件 + exact := []string{ + "/etc/passwd", + "/etc/shadow", + "/etc/gshadow", + "/var/run/secrets/kubernetes.io/serviceaccount/token", + } + for _, e := range exact { + if pp == e { + return true + } + } + + // 敏感目录前缀(UNIX 风格) + prefixes := []string{ + "/etc/ssh", + "/root", + "/etc/ssl", + "/etc/letsencrypt", + "/var/lib/docker", + "/.gnupg", + "/.ssh", + "/.aws", + "/.kube", + "/.docker", + "/.config/gcloud", + } + for _, pre := range prefixes { + if strings.HasPrefix(pp, pre) { + return true + } + } + + // Windows 常见敏感目录(小写比较) + winPrefixes := []string{ + `c:\windows\system32`, + `c:\windows\system`, + `c:\users\`, + } + for _, wp := range winPrefixes { + if strings.HasPrefix(pp, strings.ToLower(wp)) { + return true + } + } + + // 文件名级别检查 + base := filepath.Base(pp) + n := strings.ToLower(base) + sensitiveNames := map[string]struct{}{ + ".env": {}, + ".env.local": {}, + ".npmrc": {}, + ".netrc": {}, + "id_rsa": {}, + "id_dsa": {}, + "id_ecdsa": {}, + "id_ed25519": {}, + "authorized_keys": {}, + "passwd": {}, + "shadow": {}, + "pgpass": {}, + "credentials": {}, // 如 aws credentials + "config.json": {}, // docker config.json 可能含 token + } + if _, ok := sensitiveNames[n]; ok { + return true + } + // 支持 .env.* 之类的模式 + if n == ".env" || strings.HasPrefix(n, ".env.") { + return true + } + + // 扩展名级别检查 + ext := strings.ToLower(filepath.Ext(n)) + sensitiveExts := []string{ + ".pem", ".key", ".p12", ".pfx", ".ppk", ".asc", ".gpg", + } + for _, se := range sensitiveExts { + if ext == se { + return true + } + } + return false +}
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
8- github.com/siyuan-note/siyuan/commit/b2274baba2e11c8cf8901b0c5c871e5b27f1f6ddnvdPatchWEB
- github.com/siyuan-note/siyuan/commit/f8f4b517077b92c90c0d7b51ac11be1b34b273adnvdPatchWEB
- github.com/siyuan-note/siyuan/issues/16860nvdIssue TrackingPatchWEB
- github.com/siyuan-note/siyuan/security/advisories/GHSA-cv54-7wv7-qxcwnvdExploitPatchVendor AdvisoryWEB
- github.com/advisories/GHSA-cv54-7wv7-qxcwghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-23850ghsaADVISORY
- github.com/siyuan-note/siyuan/blob/master/kernel/model/file.gonvdProductWEB
- github.com/siyuan-note/siyuan/blob/v3.4.2/kernel/api/filetree.gonvdProductWEB
News mentions
0No linked articles in our index yet.