{"id":"GHSA-36v8-mpjm-8j5r","summary":"SiYuan: Cross-boundary content disclosure via getBacklinkDoc/getBackmentionDoc (publish mode): reader-reachable rendered DOM of publish-forbidden docs; sibling list endpoints are filtered","details":"**CVE:** This vulnerability corresponds to [CVE-2026-68586](https://nvd.nist.gov/vuln/detail/CVE-2026-68586).\n\n### Summary\n\nThe backlink API splits into list endpoints (which documents reference a block) and content endpoints (the rendered text of those referencing blocks). The list endpoints apply a publish-access filter, the content endpoints do not. As a result, `/api/ref/getBacklinkDoc` and `/api/ref/getBackmentionDoc` return the rendered DOM of blocks belonging to a publish-forbidden document to an anonymous reader, with no access check.\n\nBoth content endpoints are gated by `CheckAuth` only, reachable by the publish `RoleReader` token and by the anonymous account when `Publish.Auth.Enable` is `false`.\n\n### Details\n\nThe asymmetry between the list and content sides is the tell that this is an oversight, not intended behavior:\n\n| Endpoint | Returns | Publish-access filter | Route |\n|---|---|---|---|\n| `getBacklink` | list (`*Path`) | `FilterPathsByPublishAccess` - present | `CheckAuth` |\n| `getBacklink2` | list (`*Path`) | `FilterPathsByPublishAccess` - present | `CheckAuth` |\n| `getBacklinkDoc` | rendered DOM | none | `CheckAuth` |\n| `getBackmentionDoc` | rendered DOM | none | `CheckAuth` |\n\n`model/backlink.go` contains no publish-access reference anywhere, and `Backlink.DOM` is the rendered HTML of the referencing blocks. `getBacklinkDoc(defID, refTreeID)` returns the rendered content of blocks in `refTreeID` - including a publish-forbidden, publish-disabled, or password-protected document with no access check. The filtered list siblings (`getBacklink`/`getBacklink2`) demonstrate that the publish boundary is meant to apply to this data; the content endpoints simply omit it.\n\nA reader is not limited to the filtered backlink list, they call `getBacklinkDoc` directly with any `refTreeID`. This also yields a reference-existence oracle: the response reveals whether the forbidden document `refTreeID` references the block `defID`.\n\n### Proof of Concept\n\nReproduced on a local instance (SiYuan running locally, publish mode enabled on port 6808, publish Basic Auth disabled). Setup: a publish-forbidden document `D` (`REFTREEID`) whose body contains the unique marker `SECRET_MARKER_77` and which references a block `DEFID` in a separate known document.\n\n**1. Mark the target document publish-forbidden (admin action, the boundary that should block reads):**\n```\nPOST http://127.0.0.1:6806/api/filetree/setPublishAccess\nAuthorization: Token \u003cadmin-token\u003e\n{\"id\":\"REFTREEID\",\"visible\":false,\"password\":\"\",\"disable\":true}\n```\n\n**2. Baseline: the list endpoint correctly hides the forbidden doc from the reader (anonymous, port 6808):**\n```\nPOST http://127.0.0.1:6808/api/ref/getBacklink2\n{\"id\":\"DEFID\",\"k\":\"\",\"mk\":\"\"}\n```\nThe returned backlinks do not include the forbidden document `D`, the list side is filtered.\n\n**3. Disclosure: the content endpoint returns the forbidden doc's blocks anyway (anonymous, port 6808):**\n```\nPOST http://127.0.0.1:6808/api/ref/getBacklinkDoc\n{\"defID\":\"DEFID\",\"refTreeID\":\"REFTREEID\",\"keyword\":\"\"}\n```\nReturns HTTP 200; `data.backlinks[].dom` contains `SECRET_MARKER_77`, the rendered content of the publish-forbidden document, returned to an anonymous reader. `getBackmentionDoc` behaves identically for mention-type references.\n\n### Impact\n\nAn anonymous reader (publish mode with auth disabled) or any publish `RoleReader`, can read the rendered content of a publish-forbidden document's referencing blocks, defeating a boundary the administrator explicitly configured, and can determine whether a forbidden document references a given block (a reference-existence oracle).\n\n**Precondition (stated honestly):** the request requires `refTreeID` (the forbidden document's ID) and `defID` (a block it references). `defID` may be any published/known block, so if the forbidden document references any public content, `defID` is known and only `refTreeID` need be supplied. Block/document IDs for forbidden documents are also obtainable from other `CheckAuth`-only endpoints that lack the publish-access filter (reported separately). This endpoint alone does not enumerate arbitrary documents; it discloses content once an ID is known.\n\nImpact is confidentiality-only: content disclosure plus a reference-existence oracle, no modification. No admin role, CSRF token, or write permission is required. Encrypted notebooks are out of scope.\n\n### Suggested fix\n\nApply the same publish-access check the list siblings use. In `getBacklinkDoc`/`getBackmentionDoc`, filter each `Backlink` by its source document's box/path via `CheckPathAccessableByPublishIgnore` plus the publish-password cookie check consistent with `FilterPathsByPublishAccess` in `getBacklink`/`getBacklink2`. Any endpoint returning rendered block DOM should enforce the same publish boundary as the corresponding list endpoint.","aliases":["CVE-2026-68586","GO-2026-6379"],"modified":"2026-09-10T15:25:41.197209477Z","published":"2026-09-03T21:21:19Z","database_specific":{"cwe_ids":["CWE-862"],"severity":"HIGH","github_reviewed":true,"github_reviewed_at":"2026-09-03T21:21:19Z","nvd_published_at":null},"references":[{"type":"WEB","url":"https://github.com/siyuan-note/siyuan/security/advisories/GHSA-36v8-mpjm-8j5r"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-68586"},{"type":"WEB","url":"https://github.com/siyuan-note/siyuan/commit/f45749a7ef6e385f6e2af6b7dd12429d56d46f32"},{"type":"PACKAGE","url":"https://github.com/siyuan-note/siyuan"},{"type":"WEB","url":"https://www.vulncheck.com/advisories/siyuan-before-content-disclosure-via-getbacklinkdoc"}],"affected":[{"package":{"name":"github.com/siyuan-note/siyuan/kernel","ecosystem":"Go","purl":"pkg:golang/github.com/siyuan-note/siyuan/kernel"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.0.0-20260721014413-f45749a7ef6e"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/09/GHSA-36v8-mpjm-8j5r/GHSA-36v8-mpjm-8j5r.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N"}]}