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

CVE-2026-73607 — kernel

MEDIUM

CVE-2026-73607 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: Outline state for any document, including documents forbidden to readers, is returned by /api/storage/getOutlineStorage with no access check

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

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.
  • CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.

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

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-73607 by exploitation likelihood (EPSS) against impact (CVSS). Outside the shaded patch-first corner.

Where this sits among everything scored

Of 394,803 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/storage/getOutlineStorage is registered with CheckAuth only and performs no authorization of any kind. Given a document identifier it returns that document's stored outline state, regardless of the document's publish tier.

The two write endpoints for the same data, setOutlineStorage and removeOutlineStorage, both carry CheckAdminRole and CheckReadonly. Only the read path is unguarded.

Details

Routes. kernel/api/router.go:103 on master, :108 on the development branch:

ginServer.Handle("POST", "/api/storage/getOutlineStorage",    model.CheckAuth, getOutlineStorage)
ginServer.Handle("POST", "/api/storage/setOutlineStorage",    model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setOutlineStorage)
ginServer.Handle("POST", "/api/storage/removeOutlineStorage", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeOutlineStorage)

Handler. kernel/api/storage.go:466 on the development branch, :469 on master, identical. It binds docID and calls model.GetOutlineStorage(docID), which iterates the stored outline documents and returns the entry whose DocID matches. There is no filter function on this path at all: no *gin.Context, no publish-access check, no password check, no visibility check. The caller supplies the identifier and receives the payload.

What is stored. type OutlineDoc { DocID string; Data map[string]any }. The client writes it from app/src/layout/dock/Outline.ts:742:

fetchPost("/api/storage/setOutlineStorage", {
    docID: this.blockId,
    val: { expandIds: this.tree.getExpandIds() }
});

So the payload is the set of heading block identifiers the administrator has expanded in the outline pane for that document. Secondarily, an empty result versus a populated one indicates whether the administrator has ever worked with that document's outline.

Not covered by the local-storage fix. Commit 4daee87d4 addressed getLocalStorage, getLocalStorageVal, getLocalStorageVals and FilterLocalStorageByPublishAccess. The word "outline" does not appear in that diff. That filter was under-inclusive; this endpoint has no filter to be under-inclusive.

Proof of Concept

Kernel 3.7.2, publish mode on port 6808, Publish.Auth.Enable false, anonymous client with no auth header.

An administrator wrote outline state through the authenticated port:

POST /api/storage/setOutlineStorage
{"docID":"<doc id>","val":{"openIDs":["<heading id>","<heading id>"]}}
→ {"code":0,"msg":"","data":null}

The same value read back anonymously:

POST http://127.0.0.1:6808/api/storage/getOutlineStorage
{"docID":"<doc id>"}
→ {"code":0,"msg":"","data":{"openIDs":["<heading id>","<heading id>"]}}

With that document set to the forbidden tier, on the same anonymous session:

EndpointResult
getDoc (control)protyle-password--forbidden placeholder, content withheld
getOutlineStoragefull payload returned

The control establishes that the session is correctly denied the document itself.

Impact

An anonymous reader in publish mode, or any publish RoleReader, retrieves the administrator's outline state for any document whose identifier they hold, including documents in the forbidden tier that the publish filters otherwise withhold entirely. The disclosed values are heading block identifiers, usable as input to other endpoints, and the presence or absence of an entry indicates whether the administrator has worked with that document.

No document text is returned. Confidentiality only.

Suggested fix

Gate the read path as the write paths already are. Either add CheckAdminRole and CheckReadonly at the route, matching setOutlineStorage and removeOutlineStorage, or pass *gin.Context into GetOutlineStorage and apply checkBlockTreeAccessableByPublishAccess against the requested docID before returning anything.

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-73607 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/storage/getOutlineStorage` is registered with `CheckAuth` only and performs no authorization of any kind. Given a document identifier it returns that document's stored outline state, regardless of the document's publish tier. The two write endpoints for the same data, `setOutlineStorage` and `removeOutlineStorage`, both carry `CheckAdminRole` and `CheckReadonly`. Only the read path is unguarded. ### Details **Routes.** `kernel/api/router.go:103` on master, `:108` on the development branch: ```go ginServer.Handle("POST", "/api/storage/getOutlineStorage", model.CheckAut
O3 Security · Impact-Aware SCA

Is CVE-2026-73607 in your dependencies?

Find it across Go, including transitive dependencies.

CVE-2026-73607: kernel — Fix Available