CVE-2026-73609

CVE-2026-73609 is a medium-severity missing authorization vulnerability in github.com/siyuan-note/siyuan/kernel (go), affecting versions < 0.0.0-20260812083335-251596fc0de2. It is fixed in 0.0.0-20260812083335-251596fc0de2.

Does this CVE actually affect you?

Kodem shows which CVEs are reachable and running in your applications, so you fix what's exploitable, not just what's listed.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Runtime intelligence, not another scanner.

Summary

SiYuan: getBookmarkLabels returns every bookmark label in the workspace to anonymous readers, with no publish-access filtering

/api/attr/getBookmarkLabels is registered with CheckAuth only and applies no filtering of any kind. It runs a scan of the entire blocks table and returns the distinct set of every bookmark label in the workspace. An anonymous reader in publish mode receives the author's complete bookmark vocabulary, regardless of whether the bookmarked blocks live in published, hidden, password-protected or forbidden documents.

The adjacent endpoint that returns bookmarks with their blocks does filter, and does so in a way that makes the intended rule explicit: it drops a label entirely when no accessible block carries it.

Details

Route. kernel/api/router.go:297 on master, :300 on the development branch:

ginServer.Handle("POST", "/api/attr/getBookmarkLabels", model.CheckAuth, getBookmarkLabels)

No CheckAdminRole, no CheckReadonly. Reachable by the publish RoleReader token and anonymously when Publish.Auth.Enable is false.

The handler (kernel/api/attr.go) is a single line:

ret.Data = model.BookmarkLabels()

which reaches kernel/model/bookmark.go:184 and then sql.QueryBookmarkLabels() at kernel/sql/block_query.go:315:

sqlStmt := "SELECT * FROM blocks WHERE ial LIKE ?"   // "%bookmark=%"
// collect distinct ialAttr(block.IAL, "bookmark") into a set, sort, return

There is no notebook scoping, no path scoping, no publish-access check and no filter function anywhere on the path. Every block in the workspace carrying a bookmark attribute contributes its label to the result.

Bookmark labels are user-authored organisational text. They routinely name the thing being organised, which is the reason they are useful and also the reason they disclose.

The guarded sibling states the rule outright. getBookmark (kernel/api/router.go:190 on master, :193 on the development branch) carries the same CheckAuth-only exposure and handles the same data. It does this:

bookmark.Blocks = model.FilterBlocksByPublishAccess(c, publishAccess, bookmark.Blocks)
bookmark.Count  = len(bookmark.Blocks)
if bookmark.Count > 0 {
    *tempBookmarks = append(*tempBookmarks, bookmark)
}

The final condition is the significant part. The label is not merely returned with an empty block list, it is omitted from the response entirely when no accessible block carries it. The project has therefore already decided that a reader must not learn a bookmark label they have no accessible block for. getBookmarkLabels returns those same labels unconditionally, one endpoint away.

Relationship to the tag-label fix. Commit 4515fa257 ("Enforce publish access for tag labels") established that user-authored organisational labels are data the publish boundary must protect. Bookmark labels are the same class of data, drawn from the same IAL attribute store, reached through a structurally similar handler. That commit touched kernel/api/tag.go, kernel/model/publish_access.go and its test file, and nothing in attr.go or the bookmark path, so this endpoint was not covered by it.

Worth noting that the defect here is broader than the one in the tag path. The tag filter existed and checked the visible tier, so it correctly excluded forbidden documents and leaked only the password tier. getBookmarkLabels has no filter at all, so labels from forbidden documents are returned as well.

Proof of Concept

Precondition: publish mode enabled (default port 6808), anonymous when Publish.Auth.Enable is false, otherwise any publish reader account. At least one bookmarked block in a document that is not published.

POST http://127.0.0.1:6808/api/attr/getBookmarkLabels
{}

→ 200, a sorted array of every distinct bookmark label in the workspace,
       including labels used only inside documents the reader has no
       publish access to

No arguments are required. For contrast, the sibling endpoint returns nothing for those same labels to the same session:

POST http://127.0.0.1:6808/api/attr/getBookmark
{}

→ 200, labels omitted entirely where no accessible block carries them

One endpoint withholds the label, the other returns it.

Impact

An anonymous reader in publish mode, or any publish RoleReader, obtains the author's complete bookmark vocabulary across the workspace. Bookmark labels are free text chosen to describe what is being organised, so the set discloses subject matter, project names, personal and organisational names, and the general shape of what the author is working on, including material in documents that are hidden, password-protected or explicitly forbidden to readers.

Scoped honestly: this returns labels only. No block identifiers, document identifiers or content are included, so it does not extend into the identifier-to-content resolution paths. Confidentiality only, with no integrity or availability impact.

The application does not perform an authorization check before performing a sensitive operation. Typical impact: unauthorized access to restricted functionality or data.

CVE-2026-73609 has a CVSS score of 5.8 (Medium). The vector is network-reachable, no privileges required, and no user interaction. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (0.0.0-20260812083335-251596fc0de2); upgrading removes the vulnerable code path.

Affected versions

github.com/siyuan-note/siyuan/kernel (< 0.0.0-20260812083335-251596fc0de2)

Security releases

github.com/siyuan-note/siyuan/kernel → 0.0.0-20260812083335-251596fc0de2 (go)

Kodem intelligence

Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.

Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.

Already deployed Kodem?

See it in your environmentNew to Kodem? Get a demo →

Remediation advice

Mirror getBookmark. For read-only roles, build the label set from blocks that have passed FilterBlocksByPublishAccess, and emit a label only if at least one surviving block carries it. That is the rule the sibling endpoint already implements, applied to the same data.

Frequently Asked Questions

  1. What is CVE-2026-73609? CVE-2026-73609 is a medium-severity missing authorization vulnerability in github.com/siyuan-note/siyuan/kernel (go), affecting versions < 0.0.0-20260812083335-251596fc0de2. It is fixed in 0.0.0-20260812083335-251596fc0de2. The application does not perform an authorization check before performing a sensitive operation.
  2. How severe is CVE-2026-73609? CVE-2026-73609 has a CVSS score of 5.8 (Medium). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
  3. Which versions of github.com/siyuan-note/siyuan/kernel are affected by CVE-2026-73609? github.com/siyuan-note/siyuan/kernel (go) versions < 0.0.0-20260812083335-251596fc0de2 is affected.
  4. Is there a fix for CVE-2026-73609? Yes. CVE-2026-73609 is fixed in 0.0.0-20260812083335-251596fc0de2. Upgrade to this version or later.
  5. Is CVE-2026-73609 exploitable, and should I be worried? Whether CVE-2026-73609 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
  6. What actually determines whether CVE-2026-73609 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
  7. How do I fix CVE-2026-73609? Upgrade github.com/siyuan-note/siyuan/kernel to 0.0.0-20260812083335-251596fc0de2 or later.

Other vulnerabilities in github.com/siyuan-note/siyuan/kernel

Stop the waste.
Protect your environment with Kodem.