Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐹
🐹 Go
Not in CISA KEV
MEDIUM severity

CVE-2026-73605 — kernel

MEDIUM

CVE-2026-73605 is a medium-severity (CVSS 5.8) CWE-862 vulnerability in github.com/siyuan-note/siyuan/kernel. A fix is available for github.com/siyuan-note/siyuan/kernel — see the affected versions and patch details below.

SiYuan: getUniqueFilename passes an unvalidated client-supplied path to the filesystem, giving anonymous readers an existence oracle over the entire host filesystem

Also known asGO-2026-6626
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Oct 16, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

No confirmed exploitation observed yet

  • CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
  • CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.

Exploitation and automatability from CISA’s SSVC triage for CVE-2026-73605.

EPSS Exploitation Probability

via FIRST.org ↗
0.3%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs24th percentile — riskier than 24% of all scored CVEsHighest risk
0.00%0.28%0.55%0.83%0.2%0.3%0.3%Sep 26Oct 26Oct 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

CVE-2026-73605 by exploitation likelihood (EPSS) against impact (CVSS). Outside the shaded patch-first corner.

Where this sits among everything scored

Of 394,415 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Counts from FIRST.org, log-scaled.

Real-World Exposure

1 pkg affected
🐹github.com/siyuan-note/siyuan/kernel

Real-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

/api/file/getUniqueFilename takes a path from the request body and passes it to a filesystem existence check with no validation, confinement or authorization. The response distinguishes paths that exist from paths that do not, so an anonymous reader in publish mode can probe arbitrary locations on the host, one request per probe. Files and directories both work.

Every neighbouring file route either requires an administrator or confines the path first.

Details

Route. kernel/api/router.go:289 on master, :292 on the development branch, CheckAuth only.

Handler, kernel/api/file.go:84, in full:

util.ParseJsonArgs(arg, ret, util.BindJsonArg("path", &filePath, true, true))
ret.Data = map[string]any{"path": util.GetUniqueFilename(filePath)}

The argument binder does no path handling. util.BindJsonArg (kernel/util/net.go:365) takes two booleans, required (the key must be present) and rejectEmpty (the value must be non-empty). That is its entire contract. There is no filepath.Clean, no workspace join, no traversal check. An absolute path outside the workspace reaches gulu.File.IsExist unmodified.

The oracle. util/file.go:67:

if !gulu.File.IsExist(filePath) {
    return filePath
}
// otherwise loop, returning the first non-existent dir/base (i).ext

Input echoed back means the path does not exist. A (1) suffix means it does.

The asymmetry.

RouteMiddleware
putFile, copyFile, globalCopyFiles, workspaceCopyFiles, removeFile, renameFileCheckAuth, CheckAdminRole, CheckReadonly
readDir (directory enumeration)CheckAuth, CheckAdminRole
getFileCheckAuth, but GetAbsPathInWorkspace returns 403 on escape, plus rejectEncryptedBoxPath and a publish-access check
getUniqueFilenameCheckAuth, nothing else

getFile binds the identical BindJsonArg("path", &filePath, true, true) and confines it as its first action.

Proof of Concept

Kernel 3.7.2, publish mode on port 6808, Publish.Auth.Enable false, anonymous client. Reader context confirmed by getChildBlocks returning HTTP 403 on the same session.

{"path":"/etc/passwd"}
→ {"code":0,"msg":"","data":{"path":"/etc/passwd (1)"}}

{"path":"/etc/shadow"}
→ {"code":0,"msg":"","data":{"path":"/etc/shadow (1)"}}

{"path":"/etc/definitely-not-here"}
→ {"code":0,"msg":"","data":{"path":"/etc/definitely-not-here"}}

Directories behave the same way:

{"path":"/root"}      → {"path":"/root (1)"}
{"path":"/rootnope"}  → {"path":"/rootnope"}

And within the workspace, confirming whether a specific document file exists:

{"path":"<workspace>/data/<boxID>/<docID>.sy"}  → "<...> (1).sy"
{"path":"<workspace>/data/nope-no-such.sy"}     → echoed unchanged

Impact

An anonymous reader in publish mode, or any publish RoleReader, determines whether arbitrary paths exist on the host. Because directories respond the same way as files, the filesystem can be walked rather than only guessed at. This supports identifying the operating-system user's home directory, detecting installed software, backup and synchronisation directories, mapping the workspace layout, and confirming the existence of specific documents by probing their storage paths.

It also composes with the absolute workspace path returned elsewhere, which supplies a concrete prefix rather than requiring guesswork, and it recovers the operating-system username that the browser-request path strip added under issue #17410 was introduced to conceal.

Scoped precisely: nothing is read and nothing is written. This is an existence and layout disclosure, valuable primarily as a reconnaissance step.

Suggested fix

Confine the path as the adjacent getFile route does, by routing filePath through util.GetAbsPathInWorkspace and returning 403 on escape, or add CheckAdminRole and CheckReadonly to match readDir. The frontend uses this endpoint only for naming uploads and assets inside the workspace, so neither change affects legitimate use.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐹Gogithub.com/siyuan-note/siyuan/kernelall versions0.0.0-20260812083335-251596fc0de2go get github.com/siyuan-note/siyuan/kernel@v0.0.0-20260812083335-251596fc0de2

Detection & mitigation playbook

Open-source dependency
  1. Detect

    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.

  2. Fix

    Update github.com/siyuan-note/siyuan/kernel to 0.0.0-20260812083335-251596fc0de2 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-73605 is resolved across your whole dependency graph.

  3. Workarounds

    Put an independent control in front of the weakness: restrict the affected endpoint or interface to trusted networks, require an additional authentication factor or proxy-level check, and invalidate existing sessions and credentials in case the flaw has already been used.

Frequently Asked Questions

### Summary `/api/file/getUniqueFilename` takes a path from the request body and passes it to a filesystem existence check with no validation, confinement or authorization. The response distinguishes paths that exist from paths that do not, so an anonymous reader in publish mode can probe arbitrary locations on the host, one request per probe. Files and directories both work. Every neighbouring file route either requires an administrator or confines the path first. ### Details **Route.** `kernel/api/router.go:289` on master, `:292` on the development branch, `CheckAuth` only. **Handler,**
O3 Security · Impact-Aware SCA

Is CVE-2026-73605 in your dependencies?

Find it across Go, including transitive dependencies.

CVE-2026-73605: kernel — Fix Available