GitHub Advisoryadvisory · Go
GHSA-mw8r-mw84-88v2 SiYuan: Publish-boundary bypass via WebSocket broadcast: anonymous readers receive a live unfiltered feed of all edits including protected/forbidden documents (publish mode)
HIGH
Official page ↗
- Aliases
- CVE-2026-72810
- Ecosystem
- Go
- Packages
- github.com/siyuan-note/siyuan/kernel
- Severity
- High
- CVSS vector
- CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
- Weaknesses
- CWE-862
- Reviewed
- 2026-09-03
Affected packages
• Go github.com/siyuan-note/siyuan/kernel: < 0.0.0-20260723013612-ba948639d7f6 → fixed in 0.0.0-20260723013612-ba948639d7f6
Description
CVE: This vulnerability corresponds to CVE-2026-72810.
Summary
WebSocket sessions established through the publish surface (port 6808, `RoleReader` anonymous when `Publish.Auth.Enable` is `false`) are added to the same broadcast session pool as authenticated sessions. The kernel's broadcast functions push content events transactions carrying block DOM, document save/create, move/rename to every session in the pool with no role or publish-access filtering. As a result, an anonymous reader who holds a WebSocket connection open passively receives a real-time feed of every edit made in the workspace, including edits to password-protected, publish-forbidden, and unpublished documents. Because these events are delivered over the push channel and never pass through an HTTP handler, none of the publish-access filters that gate the HTTP endpoints apply.
Details
Session admission. `HandleConnect` admits the injected `RoleReader` publish token, and the session is registered via `AddPushChan` into the same `sessions` pool used for authenticated clients.
Unfiltered broadcast. The broadcast functions (`Broadcast`, `broadcastOthers`, `broadcastOtherAppMains`, …) write to every session in the pool with no role or publish-access check. The `isPublish` flag on a session is consulted only to send the "service closed" notice it is never used to gate content. Content events are pushed via `PushModeBroadcast → Broadcast()`, so transactions (with rendered block DOM), `savedoc`/create, and `moveDoc`/rename events reach the publish reader's socket unfiltered.
No HTTP filter applies. This is a push channel, the events originate from the kernel's own edit pipeline and are broadcast directly to open sockets. They never traverse an HTTP handler, so the publish-access filters that gate the HTTP content endpoints (and the incomplete/missing filters reported separately on those endpoints) are not in the path at all. The WebSocket route (`/ws`) is `CheckAuth`-only, which the publish `RoleReader` token satisfies.
Proof of Concept
Reproduced on a local instance (SiYuan running locally, publish mode enabled on port 6808, publish Basic Auth disabled). An anonymous client (no token, no password) opens `wss://127.0.0.1:6808/ws` and holds it open while an administrator edits documents in the workspace.
The anonymous socket received, in real time and unfiltered:
• `updateAttrs` with `name=WS_LEAK_SECRET_9931` on a block whose `rootID` is a password-protected document.
• The secret title `WS_SECRET_DOC_7742` of a newly created document.
• The create event carrying the notebook (box) name `CritChain` and the document path.
No HTTP request was made beyond the WebSocket upgrade; the content arrived over the push channel.
Impact
An anonymous reader (publish mode with auth disabled) or any publish `RoleReader` who merely holds a WebSocket connection open receives a live feed of every edit an administrator makes: block DOM, attributes, titles, notebook names, and document structure, including for password-protected, publish-forbidden, and unpublished documents. This defeats the publish-access and publish-password boundaries entirely for any content edited while the socket is open. The precondition is trivial: an administrator active in the workspace while the anonymous socket is connected. Confidentiality-only (passive disclosure); the channel is receive-only for the reader. Encrypted-notebook content follows the same broadcast path if edited while unlocked.
Suggested fix
Filter broadcasts by session before writing: for any session flagged `isPublish`, apply the same publish-access/publish-ignore/publish-password checks used on the HTTP content path before pushing a content event, or exclude publish sessions from content broadcasts entirely and deliver only the events a publish viewer is authorized to see. The `isPublish` flag is already present on the session; it should gate content, not only the service-closed notice.
Related
Alias · CVE (1)
- CVE-2026-72810 SiYuan versions before v3.7.4 contain a publish-boundary bypass vulnerability in WebSocket broadcast sessions that allows anonymous readers… vulnerability
Weakness · CWE (1)
- CWE-862 Missing Authorization weakness
References
- https://github.com/siyuan-note/siyuan/security/advisories/GHSA-mw8r-mw84-88v2 web
- https://nvd.nist.gov/vuln/detail/CVE-2026-72810 advisory
- https://github.com/siyuan-note/siyuan/commit/ba948639d7f6bd5594ce584072dc68310da87a68 web
- https://github.com/siyuan-note/siyuan package
- https://www.vulncheck.com/advisories/siyuan-before-publish-boundary-bypass-via-websocket web