SiYuan: Notebook name, document count, size and timestamps are returned for any notebook, including notebooks hidden from readers, by /api/notebook/getNotebookInfo
Published Aug 12, 2026 · Updated Oct 24, 2026 · Also known as GHSA-74pj-6g7r-j55c
Original summary
Normalized public record · Updated Oct 24, 2026
SiYuan: Notebook name, document count, size and timestamps are returned for any notebook, including notebooks hidden from readers, by /api/notebook/getNotebookInfo
Publisher and source text is retained separately from QFinch interpretation.
QFinch assessment
/api/notebook/getNotebookInfo is registered with CheckAuth only and applies no authorization check of any kind. Given a notebook identifier, it returns that notebook's author-written name, document count, total size and creation and modification timestamps. It does so for every notebook the server has loaded, including notebooks that lsNotebooks deliberately withholds from readers because they are closed or not publish-visible.
Potential impact
An anonymous reader in publish mode, or any publish RoleReader, can read the author-written name, document count, total size and activity timestamps of notebooks that are closed or not published, which are exactly the notebooks the notebook lister withholds from them. Notebook names are free text chosen by the author and routinely describe their contents. Document count and size indicate scale, and the modification timestamp reveals recent activity in a workspace area the reader has no access to. Confidentiality only, with no integrity or availability impact, and no document content is disclosed.
Technical context
| Item | Detail | |---|---| | Route | kernel/api/router.go:123 POST /api/notebook/getNotebookInfo → model.CheckAuth → getNotebookInfo | | Middleware | CheckAuth only, no CheckReadonly, no CheckAdminRole | | Guard in handler | None. IsReadOnlyRoleContext, publishAccess, Visible and Closed all return zero matches | | Exposed | BoxInfo{ID, Name, DocCount, Size, HSize, Mtime, CTime, HMtime, HCtime} | | Affected refs | eef105683 (v3.7.3, master HEAD) and v3.7.4-alpha.1, handler identical on both | The handler. It validates boxID against the ID pattern, calls box := model.Conf.Box(boxID), returns a not-found response if that is nil, and otherwise returns box.GetInfo() unmodified. GetInfo() (kernel/model/box.go:470) walks the notebook's files and returns the metadata listed above. There is no ownership check and no publish-access check anywhere on the path. The nil branch is also a minor existence oracle: a valid-format identifier that names no loaded notebook is distinguishable from one that does. Guarded sibling. lsNotebooks, the notebook lister, is also reader-reachable and does filter. For read-only roles it skips any notebook where notebook.Closed holds, and skips any notebook whose publish-access entry has !item.Visible. The codebase therefore intends closed and non-published notebooks to be invisible to readers. getNotebookInfo returns their name and statistics to any reader who supplies the identifier. Precedent. GHSA-f2rw-w22v-54vh restricted getEncryptedNotebookStatus, which disclosed encrypted-notebook names and lock state, to administrators. getNotebookInfo is the non-encrypted analogue, disclosing regular notebook names and statistics including for notebooks outside the reader's publish scope, and was not restricted. Reachability, stated precisely, because it differs by branch. On v3.7.3 a reader can obtain the identifier of a notebook they cannot see, by chaining two endpoints that are currently ungated on that branch. getBlockDefIDsByRefText returns block and document identifiers workspace-wide, including from hidden notebooks. getPathByID then returns the owning notebook identifier for any such block, in its notebook field. getFullHPathByID additionally discloses the notebook name directly. The chain requires no special conditions beyond a reference text that occurs somewhere in the workspace. On the development branch those sources are already closed. getPathByID now gates through CheckBlockIdMetadataAccessableByPublishAccessInBox, getIDsByHPath through filterFileTreeBlockIDsByPublishDiscoverability, and getBlockDefIDsByRefText and getFullHPathByID are likewise gated. Notebook identifiers are a fourteen-digit timestamp plus seven random characters, and Conf.Box(boxID) returns non-nil only for loaded notebooks, so guessing is not practical. A reader-reachable route on the development branch that yields the identifier of a hidden notebook was not found. So on the development branch this is defence in depth rather than a live path. It is reported because the handler itself remains unguarded on both branches, and because closing it removes any dependence on those identifier sources staying gated in future.
Evidence: public source recordsAffected products
| Affected package, product or range | Fix status |
|---|---|
| Consult the referenced vendor advisory for affected versions. | Consult source advisory |
Matching a version is only one part of assessing exposure. QFinch has not assessed your environment on this public page.
Remediation
Apply the vendor-supported fixed release or mitigation, then verify the affected component is no longer reachable.
- Confirm the affected product and reachable code path exist in your environment.
- Apply the vendor-supported patch or mitigation from the primary advisory.
- Rescan the exact deployed revision and retain verification evidence.
Evidence coverage
- SSVC priority
- LOW
- Confidence
- Not available
- Aliases
- GHSA-74pj-6g7r-j55c
Scores appear only when corresponding evidence exists. Missing data is never interpreted as zero risk.
Sources and record history
- Security advisory ↗
- VulnCheck Advisory: SiYuan before v3.7.4 Information Disclosure via getNotebookInfo ↗
Record history
Published Aug 12, 2026 · Last refreshed Oct 24, 2026